r/swift

▲ 27 r/swift

Embedded Swift forces you to write better code

Hot take, but compiling Swift in embedded mode restricts you to write plan simple code.

The moment you start abusing generics you get a compiler error instead of an over engineered solution!

reddit.com
u/functionallycorrect — 1 day ago
▲ 16 r/swift+2 crossposts

SwiftUIBackportKit – A lightweight library for supporting multiple iOS versions in SwiftUI

Hi everyone!

One pain point I've run into repeatedly with SwiftUI is supporting newer APIs while keeping an older deployment target.

Things like `if #available` work well in normal Swift code, but they don't fit naturally in the middle of a modifier chain. That often leads to duplicated views or compatibility helpers scattered throughout a project.

After solving the same problem across multiple apps, I decided to package the patterns into a small open-source library called **SwiftUIBackportKit**.

It includes:

• `.modify { }` for conditional view transforms
• `.backport` for reusable version-gated SwiftUI APIs
• `platformValue(...)` for version-specific values
• `OS.isAtLeast(_:)` for simple runtime version checks

The goal is to keep SwiftUI views focused on describing the UI while isolating deployment-target compatibility in one place.

GitHub:
https://github.com/EmadBeyrami/SwiftUIBackportKit

I'd really appreciate any feedback on the API design, naming, or features you'd like to see. And if you find it useful, a ⭐ on GitHub would mean a lot!

Thanks!

github.com
u/NoCardiologist4405 — 1 day ago
▲ 6 r/swift+1 crossposts

How long did Advanced swift (objc.io) actually took you to finish?

I’m a few chapters into Advanced swift by objc.io right now. The concepts are super dense which is great and I’m learning a lot! Really some concepts are just WOW!!!

Usually I’ve noticed for me that concepts to sit clearly in my brain and understanding takes a little longer than I expected so I’m just curious to know how long it took you folks to finish the book? Did you read end to end and also understood the code ? Or cherry picked the topics and studied them need to need basis?

Thank you in advance :)

reddit.com
u/StockStart825 — 2 days ago
▲ 36 r/swift+1 crossposts

I shipped a 100-level game on macOS and iOS with no game engine - CGContext into an IOSurface, presented through Metal

I spent the last year building an arcade game in Swift without an engine. The renderer ended up somewhere I did not expect, so it seemed worth writing up properly.

The shape of it:

- Drawing is CGContext. Not SpriteKit, not custom Metal shaders for the game content - actual Core Graphics 2D calls, because the game is polygons and.gradients rather than sprites. Everything is drawn, nothing is blitted.

- That context is backed by an IOSurface, presented zero-copy through Metal. The obvious alternative - render into a CGBitmapContext, then hand the bytes to Metal - measured 5 to 10 times slower. That experiment is still in the repo as an archived failure rather than deleted, because the measurement is the useful part.

- One codebase renders on both AppKit and UIKit. The platform layer is a handful of files - display link, input, haptics - and the roughly 7,600-line renderer is shared verbatim between Mac and iPhone.

- iOS has a thermal governor: sustained load steps the frame rate 60 to 30 so a long session does not cook the phone. On device, a render scale of 1.5 turned out to be the 60fps sweet spot; 2.0 fell off a cliff.

- Gradients are memoized - about 166 cached. Allocating them per frame was the single largest early performance win, and it was not close.

The thing I would tell anyone considering this: a hand-rolled renderer was the right call for this specific game, because it is 2D vector-ish content where Core Graphics is genuinely good, and it would be the wrong call for almost anything else. I would not do it for a sprite-based game. I would not do it for 3D. The reason it worked is that the drawing model matched the art style, not because engines are bad.

The game is VYRON, 99c, Universal Purchase across Mac and iPhone:
https://apps.apple.com/us/app/vyron/id6778002261

Happy to go into any part of it in the comments.

u/One-Tea8742 — 3 days ago
▲ 12 r/swift+5 crossposts

Local LLM on the Apple Silicon Macs

I've been messing with on-device AI stuff for Apple Silicon Macs and put together LocalLM Lab to make experimentation easier.

It started as a simple prompt interface as just a way to poke at Apple's on-device foundation model and see how it responds. Since then I've added an OpenAI API-compatible endpoint (localhost or external IP), so you can point existing tools/scripts at it like any other local model server.

Right now it's built on Apple's Foundation Models framework. With the new LanguageModel protocol Apple introduced this year, the framework isn't locked to Apple's on-device model anymore. Any provider that ships a conforming Swift package (local MLX models, Claude, Gemini, etc) should be a plug-in. I'm looking at wiring that up so LocalLM Lab isn't limited to just the built-in model.

It's a free download from thisbrain.ai/locallm

Let me know how you think LocalLM Lab should evolve. MCP? Model switching in the UI? Something else?

u/AdventurousKeys — 3 days ago
▲ 10 r/swift+3 crossposts

I've been building a tool for migrating CocoaPods projects to SwiftPM

Hey,

I've been working on this for a while and thought I'd share it here.

It's called PkgLift and basically, I wanted an easier way to deal with moving older Xcode projects from CocoaPods to Swift Package-manager.

I know you can obviously do this manually but I didn't really like the idea of going through everything by hand, especially on projects with a many dependencies!

The thing I was worried about when building it was making a tool that just changes a bunch of stuff and assumes it worked. So PkgLift doesn't really work like that.

You first run:

pkglift analyze
pkglift plan

and it tries to work out what it actually knows how to migrate.

If it isn't sure about something it just leaves it alone instead of trying to guess.

Then you can check the plan yourself before actually changing anything.

If it looks good:

pkglift migrate --apply
pod install
pkglift verify

That's pretty much the idea.

It is still early and I'm sure there are plenty of CocoaPods setups that I haven't thought about yet, which is actually one of the reasons I'm posting it here.

You can install it with:

brew install Alexsvensson99/tap/pkglift

Repo:
https://github.com/Alexsvensson99/PkgLift

If anyone has an old CocoaPods project lying around and wants to try it, I'd be interested to know what happens. Especially if it fails on something weird :)

u/Plenty-Historian9510 — 4 days ago
▲ 4 r/swift

How would you test a seeded random workout generator in Swift?

My iOS app generates workouts from a set of exercises and constraints. I want the same inputs to be reproducible in tests and previews, while production still feels random. Would you inject a seeded RNG, pass a generator protocol through the model, or keep randomness at the edge and test the generated constraints instead? I’m looking for a small approach that won’t make the app’s architecture noisy.

reddit.com
u/UkrMalt — 4 days ago
▲ 77 r/swift+12 crossposts

I created a RecognitionService that handles system-wide voice input fully on-device (no Google, no network)

Most voice input on Android - SpeechRecognizer.createSpeechRecognizer(context) calls — gets routed to Google's network-backed recognizer. I wanted that path to run locally, so I wrote one.

The service hooks the framework's SpeechRecognizer API. Once it's set as the default, any app calling createSpeechRecognizer(context) (no ComponentName) ends up in our pipeline and gets back transcription that never left the device. Pipeline is Silero VAD + Parakeet TDT v3 (114 languages, ~890 MB INT8) on ONNX Runtime with NNAPI.

Honest caveat: Gboard, Samsung Keyboard, and Google Assistant ship their own recognizers and skip the system default. So the default-IME voice button on most phones won't go through this. What does: accessibility tools, custom dictation UIs, and anything calling the framework API directly.

Models download on first use (~1.2 GB) via a foreground WorkManager job so it survives backgrounding. After that, fully offline.

Setup + demo APK: github.com/soniqo/speech-android

audio.soniqo:speech:0.0.9 on Maven Central

Library:

Happy to answer questions about the binder lifecycle, the foreground worker setup, or why SpeechRecognizer is such a tarpit of edge cases.

u/ivan_digital — 6 days ago
▲ 14 r/swift

I made a Liquid Glass lens tinting control for UISegmentedControl: glyphs take the accent exactly where the glass covers them

Actually claude made it but whatever. If you wanted a segmented picker that looks like the one apple uses in their native apps (health, photos, fitness) then here's the closest I've gotten. Have fun

github.com
u/WhiteTitanium — 5 days ago
▲ 30 r/swift

Anyone interested in learning SpriteKit together?

I’m an iOS developer working professionally mainly with UIKit. I’ve been working with Swift for a while, but haven’t really explored game development on Apple platforms. I’m about to start learning SpriteKit properly from the fundamentals and eventually want to build something with it.

Looking for someone who’s also learning it and wants to keep each other accountable. We can share what we worked on, discuss concepts, and help each other out when we get stuck.

If you’re interested, DM me.

reddit.com
u/Itchy-General-7278 — 8 days ago
▲ 26 r/swift

Made a weather app for my weekly commute, would anyone find this useful?

I combined apple weather data with radar data to get a more accurate view what my day looks like. Still looking into radar future-cast data, if anyone has advice on providers who can supply 6-8 hrs ahead.

https://testflight.apple.com/join/PUjCeSZP

Edit: TestFlight link^

u/RusticPotato123 — 9 days ago
▲ 76 r/swift

DOOM on Apple Neural Engine(ANE) via Core AI!!!!!

[UPDATE]
After staring at the code for a while, I realized that I had simply been taking the DOOM screen—processed by the CPU—and mapping it as a texture onto a rectangle rasterized via ANE. I had mistakenly thought DOOM was outputting vertex data. How embarrassing... 😂 

I plan to try again later with a proper 3D game that actually uses vertex data. 

Hello everyone.

We have successfully ported DOOM's rendering to the Apple Neural Engine (ANE), and have successfully run Apple's AI/deep learning silicon as a 3D graphics accelerator via Swift 6 and Core AI!

CPU usage is high, around 40%, but the ANE is running.

  • DOOM's frame buffer has an original resolution of 640x400 (320x200), but it is converted to 256x256 by a custom texture model and then transferred to a 64-channel ANE rasterizer model.

  • Apparently

    func updateTexture(pixelData: [Float16]) {

    guard let doomPixels = gp_DoomScreenBuffer else { return }

    let actualWidth = 640 let actualHeight = 400 let totalPixels = actualWidth * actualHeight

    var doomFP16Buffer = [Float16](repeating: 0.0, count: 3 * totalPixels)

    let rOffset = 0 let gOffset = totalPixels let bOffset = totalPixels * 2

    for i in 0..<totalPixels { let argbPixel = doomPixels[i] doomFP16Buffer[rOffset + i] = Float16((argbPixel >> 16) & 0xFF) / 255.0 doomFP16Buffer[gOffset + i] = Float16((argbPixel >> 8) & 0xFF) / 255.0 doomFP16Buffer[bOffset + i] = Float16(argbPixel & 0xFF) / 255.0 }

    var texView = self.rawTextureArray.mutableView(as: Float16.self) texView.copyElements(fromContentsOf: doomFP16Buffer) }

This function seems to be increasing CPU usage.

We welcome your comments and feedback!

GitHub: https://github.com/kamisori-daijin/Magnesium/tree/ane-doom

(ane-doom Branch)

Demo:

https://i.redd.it/mvb9rrr5eoih1.gif

https://preview.redd.it/uljd9gs7eoih1.png?width=546&format=png&auto=webp&s=a6e60cc6938bd71c7330585c38c4bf386a9fd827

reddit.com
u/AdhesivenessSea9511 — 9 days ago
▲ 16 r/swift

Is foldable support on anyone’s roadmap yet?

If the folding iPhone ships this fall, apps would need to reflow mid-session into something closer to an iPad ratio — layouts, state preservation, whether the unfolded canvas gets a sidebar at all.
Is anyone budgeting time for that before September? Or waiting to see the hardware and assuming automatic resizability carries you until users complain?

reddit.com
u/Turbulent_Ad_1039 — 9 days ago
▲ 0 r/swift

Built a native macOS app that rewrites AI drafts in your own voice — open source, Swift

I write a lot of AI-assisted content (LinkedIn posts, docs, etc.) and got tired of the "sounds like AI" problem. Em-dash overuse, "moreover/furthermore," hedge-everything phrasing, that overly-symmetric triplet-list structure. So I built Humanizer: it takes an AI draft and nudges it toward how you actually write, based on a voice profile it learns from your own edits over time.

V1 was a Python/FastAPI backend with a browser-based local UI. Just shipped a proper native macOS version. Signed, notarized, real DMG, built in Swift rather than wrapping the original web UI.

A few things about the design that might be relevant to this sub:

- Provider-agnostic: abstracted interface over Claude (Anthropic) and OpenAI. Swap via config. No hardcoded API calls scattered through the codebase.

- No black-box voice model: the "voice profile" is a plain, human-readable/editable file, not an embedding you have to trust.

- Hard content/style boundary: it only ever touches wording and rhythm. Facts, claims, numbers are never touched. Edits get classified (style vs. content) via LLM call before anything gets absorbed into the learned voice. This means a factual edit you make later never accidentally "teaches" the tool the wrong thing.

- No auto-posting, anywhere. Paste out, edit, paste back. You always publish it yourself.

- Runs fully local, no telemetry, no accounts.

Open source, MIT licensed: github.com/ancientcomputing/humanizer

Would love feedback on the Swift side in particular. If anything in the project structure or API usage looks off, tell me.

Meta note: this post was AI-drafted, then run through Humanizer itself before I posted it. Curious if anyone here can spot what's still giving away the AI in the wording.

u/AdventurousKeys — 8 days ago
▲ 9 r/swift+1 crossposts

Scaffolding 3.4.0 - simple coordinator SPM

Hey!

Scaffolding 3.4.0 got released. It's a SwiftUI coordinator pattern navigation library for iOS 18+ that allows creating modular navigation flows through linked list structure, allowing easy syntax and modularization - macro powered, with easy setup and rapid prototyping capabilities.

This is pretty much QOL version, which adds easier way to fully test the navigation, debugging options, async/await syntax and simple complete state restoration (some limitations apply).

Updated demo is in Example/ directory and docs (dotaeva.github.io/scaffolding/) now include more cases.

For those who used Stinsen, this is very similar in use. Feel free to submit other QOL ideas.

github.com
u/Good-Confusion-8315 — 8 days ago
▲ 6 r/swift+1 crossposts

BLE user trilateration

Has anyone here worked on a POC for indoor user positioning using BLE beacons?
I’m currently exploring this and would love to know what pipeline/approach you guys have used — RSSI filtering, distance calculation, trilateration/fingerprinting, Kalman filter, etc.
If you have any POCs, GitHub repos, papers, or reference material, please share. Would really appreciate it!

reddit.com
u/genysis_0217 — 8 days ago
▲ 2 r/swift+3 crossposts

Tile Wipeout — a new kind of slider puzzle where you rotate rows and columns to eliminate tiles by guiding them past matching gates [beta, full game rules included in post]

Feedback would be appreciated! Have fun!

Gameplay video: https://www.youtube.com/watch?v=lC34LO_bL4k

Beta link: https://testflight.apple.com/join/3sstMjRK [iOS/iPadOS/macOS]

Intro

Tile Wipeout is a row-and-column rotation puzzle about matching colors and shapes.

You rotate rows and columns to move tiles through fixed gates. Matching a tile's color and shape to a gate removes the tile, while other tiles cause both the tile and gate to change shape.

Empty spaces passing through gates create new tiles.

Your goal is to leave as much of the grid empty as you can in the given number of moves. Note that removing every tile may not always be possible.

Game Rules

Objective

The game is played on a 6 × 6 grid using six colors.

Each color begins with:

  • 1 gate
  • 5 tiles

The six gates are fixed in place. They cannot move or be removed. Every row and every column contains exactly one gate.

Your goal is to leave as many of the grid's 30 non-gate cells empty as possible in the given number of moves.

Shapes

Every tile and gate has one of two shapes:

  • Square
  • Circle

A tile can be removed only when both its color and its shape match the gate it passes through.

Making a Move

Swipe any row or column to rotate its tiles and empty spaces by one position.

Anything that passes an edge wraps around to the opposite edge. The gate remains fixed in place.

During each rotation, exactly one tile or empty space passes through the gate. That interaction may change the passing tile and the gate. Everything else simply moves to its new position.

Passing Through a Gate

There are three possible interactions:

  • A matching tile is removed.
  • Any other tile causes both shapes to change.
  • An empty space creates a new tile.

Matching tile

When a tile matches both the gate's color and shape, the tile is removed, leaving an empty space.

For example:

  • A square blue tile is removed by a square blue gate.
  • A circle red tile is removed by a circle red gate.

The gate does not change when it removes a tile.

Any other tile

If a tile does not match both the gate's color and shape, both the tile and gate change shape:

  • Square becomes a circle.
  • Circle becomes a square.

Their colors do not change.

For example, when a circle green tile passes through a square green gate:

  • the tile becomes a square
  • the gate becomes a circle

Matching is checked before either shape changes, so the tile is not removed during that move.

Similarly, when a square green tile passes through a square red gate:

  • the tile becomes a circle
  • the gate becomes a circle

The tile is not removed because its color and shape did not both match the gate before the shapes changed.

Empty space

When an empty space passes through a gate, it becomes a new tile with the gate's current color and shape.

The gate does not change.

The newly created tile cannot be removed during the same move.

Reversing a Move

Every move can be reversed by swiping the same row or column in the opposite direction.

Reversing restores the previous board position, including any removed or created tiles and any shape changes.

The reverse swipe still costs one move.

Tile Sizes

Among tiles of the same color, larger tiles are closer to the gate of that color.

Tile sizes update as the tiles move. Size does not affect how tiles interact with gates.

Ending the Game

The game ends when you run out of moves.

You may also end the game early. Removing every tile may not always be possible.

Scoring

Score = (% empty × 1000) + moves remaining

The empty percentage is the percentage of the grid's 30 non-gate cells that are empty.

Beta

https://testflight.apple.com/join/3sstMjRK [iOS/iPadOS/macOS]

u/amichail — 7 days ago
▲ 11 r/swift

How are you handling SwiftData in a layered architecture?

SwiftData models are reference types with their own change tracking, which makes them awkward to pass around outside the view layer — they carry the context with them and you end up coupled to it everywhere.
What I’ve settled on is wrapping ModelContext in a client with explicit methods and mapping to plain structs at the boundary, so nothing above the data layer knows SwiftData exists. Testing gets easy, cost is the mapping layer.
Curious whether people are doing something less manual, or whether you just let the models flow through and accept the coupling

reddit.com
u/Turbulent_Ad_1039 — 9 days ago