ThinkBud + Foundation Models: What I Shipped On-Device, and the Wall That Sent Me Back to the Server
Day 10 of the 30-day iOS series, the build-in-public finale of AI week. I took the on-device Foundation Models stack from Days 8 and 9 and bolted it into ThinkBud, an app I actually ship. Here's the honest field report: the bounded tasks the on-device model nailed for free and offline, the context-window wall a 100K-character textbook import smashed into, and the exact line of code where I gave up and routed to a server. Plus the one decision that's pure Swift — so it gets a real test.
@Generable: Make Apple's On-Device Model Hand You a Swift Struct, Not a String to Parse
Day 9 of the 30-day iOS series, part 2 of AI week. Yesterday Foundation Models gave us a String. Today we make it give us a typed Swift value — BrewSummary(flavor:, advice:, rating:) instead of a paragraph you regex your way through. @Generable, @Guide constraints, session.respond(to:generating:), and the sleeper-within-the-sleeper: tool calling, where the on-device model calls your own Swift code mid-answer. With the TDD seam, because typed output changes what you test.
Foundation Models: Your First On-Device AI Feature With No Backend, No API Key, No Bill
Day 8 of the 30-day iOS series, and the start of AI week. The Foundation Models framework runs a real language model entirely on the phone — free, private, offline. We build the smallest thing that works: summarize a block of text in three lines, handle the availability cases that bite in production, wire it into a real app, and put a TDD seam around the part that isn't the model. Code-along, with tests.
UIDesignRequiresCompatibility: When (and Why) Opting Out of Liquid Glass Is the Pro Move
Apple hands you one Info.plist key that freezes the old design for a full year. It's not a cop-out — for banking, enterprise, and apps caught mid-redesign, opting out of Liquid Glass is the responsible call. The exact flag, a real before/after from my own app, the deadline, and a decision matrix you can actually defend in a standup. Plus the per-screen rollout gate you should be testing instead.
Icon Composer and the New App-Icon Era: One Document Instead of Three Exported PNGs
iOS 26 wants your app icon in light, dark, clear, and tinted. The old way was three flat 1024px PNGs that quietly drifted apart. Icon Composer turns it into one layered .icon document the system relights for you. The real workflow from a single SVG to a full set — plus the one decision around icons you can actually unit-test.
Custom Liquid Glass Components: When to Leave the Defaults (and the Three Mistakes That Kill Your Frame Rate)
glassEffect(.regular, in:) with a custom shape, two glass blobs that morph into each other with glassEffectID, and the three things that turn buttery Liquid Glass into a stutter machine. Built on a real iPhone 17 Pro simulator, with the TDD seam that keeps the decision testable even though the render isn't.
Liquid Glass for an App You Already Shipped: What You Get From a Recompile vs. Five Lines of Tuning
I rebuilt a real SwiftUI app against the iOS 26 SDK and took two screenshots of the exact same screen — one with zero code changes, one with five lines of glassEffect. Here's the honest split between what the recompile hands you for free and what's worth your custom-tuning time, plus the TDD seam that makes a visual feature testable.
Migrating a Real App to Swift 6.2 Strict Concurrency: 86 Errors, One Afternoon, One Race Condition I Didn't Know I Had
I migrated Invoize from Swift 6.0 strict mode to Swift 6.2 approachable concurrency on a Sunday afternoon. Every warning, every fix, the one real race condition the compiler finally surfaced — and the TDD seams I leaned on so the migration wasn't just compiler-driven guessing.
@concurrent vs nonisolated vs @MainActor: The Swift 6.2 Decision Tree That Fits on a Napkin
Four real scenarios — UI update, network call, image decode, file IO — and exactly which Swift 6.2 isolation keyword each one needs. A TDD walk-through with Swift Testing, no whiteboard ceremony required.
MainActor by Default: Why Apple Just Reversed Swift's Concurrency Story
Xcode 26 flips the default — your code now runs on the main actor unless you say otherwise. Here's why Apple changed direction, what it actually means for your existing project, and a TDD walk-through showing the migration in real Swift.