Your Username Has an Underscore. SwiftUI Just Rendered Half of It in Italics.
AttributedString and Text(_:) both parse Markdown by default in SwiftUI. That's great for your own copy and a landmine for anything that echoes user-generated text back onto the screen. Here's the actual fix.
SwiftUI's Purple Warning Isn't Cosmetic. 'Publishing Changes From Within View Updates' Means You Raced Your Own Render.
Xcode's console warns 'Publishing changes from within view updates is not allowed, this will cause undefined behavior' and most developers just scroll past it. Here's what SwiftUI is actually telling you, the three common ways you trigger it, and why ignoring it eventually costs you a view that won't stop re-rendering.
SwiftUI's .onAppear Doesn't Mean 'First Appearance.' It Means 'Any Appearance.'
onAppear fires every time a SwiftUI view becomes visible again, not just once — including every time you pop back to it in a NavigationStack. Here's why that duplicates network calls and how to fix it with .task(id:) or a one-shot flag.
Your Pull-to-Refresh Spinner Vanishes Instantly. Your .refreshable Closure Isn't Actually Async.
SwiftUI's .refreshable modifier hides its spinner the moment your closure returns — not when your data arrives. Here's the fire-and-forget Task bug that causes it, and the fix.
GeometryReader Doesn't Report Your View's Size. It Reports the Size It Forced On Everything Inside It.
GeometryReader looks like a harmless way to read a view's size in SwiftUI, but it's a greedy layout container that overrides its children's sizing — here's the gotcha, and the modern alternatives that avoid it.
You're Creating a New DateFormatter on Every Cell Scroll. That's the Lag You Can't Explain.
DateFormatter and ISO8601DateFormatter are expensive to initialize — locale and calendar setup included — and creating one inside a loop or a SwiftUI view body is a quiet, common performance bug. Here's the actual cost and the fix.
NavigationPath Hides Your Routes Behind Type Erasure. Deep Linking Wants Them Back.
SwiftUI's NavigationPath makes heterogeneous navigation stacks easy to push onto — and nearly impossible to inspect, restore, or deep-link into without a Codable detour. Here's the actual trade-off and how to navigate it.
SwiftUI's .task(id:) Cancels for You. .onChange Doesn't. That Gap Is Where Your Duplicate Network Calls Live.
.task(id:) and .onChange(of:) both react to a value changing, but only one of them cancels the work it started. Here's the SwiftUI concurrency gotcha that ships silently duplicate requests.
Your Child View Needs to Tell Its Parent Something. A Binding Is the Wrong Tool.
@Binding is great for two-way state you own. It's the wrong tool when a child view needs to report something upward that it doesn't own — a measured size, a scroll offset, a list of anchors. That's what PreferenceKey is actually for.
@FocusState Looks Simple. Programmatic Focus in SwiftUI Isn't.
@FocusState works great for the demo. Then you add a 'Next' button, a sheet, or a ForEach, and focus starts silently failing. Here's why, and the patterns that actually hold up.
Your SwiftUI List Scrolls Like Mud. The Images Aren't the Problem — Decoding Them at Full Size Is.
Loading a photo into a 60pt thumbnail still decodes it at full resolution unless you tell iOS otherwise. Here's the actual fix: CGImageSourceCreateThumbnailAtIndex, why UIImage(data:) alone doesn't help, and how to downsample before a pixel ever hits the view.
Custom @Environment Values Used to Need Five Lines of Boilerplate. Now They Need One.
The @Entry macro replaces the EnvironmentKey struct, defaultValue, and extension boilerplate every custom SwiftUI environment value needed — but it changes a couple of defaults you should know about before you migrate.
SwiftUI Cancels Your .task When the View Disappears. Your await Doesn't Get the Memo.
SwiftUI's .task modifier automatically cancels its Task when a view disappears — but cancellation is cooperative, not magic. Here's why your network call keeps running anyway, and the three checks that actually stop it.
AsyncImage Looks Like Free Image Loading. It Isn't Caching Anything.
AsyncImage handles the download and the loading spinner, so it feels like it's handling caching too. It isn't — scroll a list past a row and back, and it fetches the same image again. Here's why, and a caching wrapper that actually fixes it.
'One Codebase, 3x Faster.' A Real Team's Flutter Pitch Met Six Years of Native Reality.
A mobile lead's boss wants to rewrite a 100K-user native app in Flutter to ship '3x faster.' The Reddit thread that followed is the clearest native-vs-cross-platform argument I've read this year — AI angle included.
@AppStorage Looked Like Free State Management. It Isn't Watching What You Think.
@AppStorage feels like @State that happens to persist. It's actually a thin wrapper over UserDefaults with a KVO bridge bolted on, and that difference bites the moment a widget, an app extension, or a background task touches the same key.
SwiftUI Reset My State for No Reason. The Bug Was Identity, Not Bindings.
A text field kept clearing itself on every re-render, and no amount of staring at @State fixed it. The actual cause was SwiftUI's view identity system silently deciding my view was a brand new one. Here's how identity actually works and the three ways to break it.
VoiceOver in SwiftUI: The Five Bugs Your Beautiful UI Is Hiding
SwiftUI gives you accessibility almost for free, until the moment it doesn't. A practical checklist of the five VoiceOver bugs that show up in real apps, and the SwiftUI modifiers that actually fix them.
Embedded Swift Won't Let You Cheat. Turns Out That's a Feature.
Embedded Swift bans existentials, reflection, and the Objective-C runtime to fit Swift on microcontrollers. The restrictions it enforces are the same discipline that makes regular iOS code faster — and BrewLog's own networking layer breaks the rule on line one.
String Catalogs Made Localization Easy. Then I Found the Four Things They Don't Catch.
Xcode's String Catalogs replaced .strings files and genuinely fixed the worst parts of iOS localization. But automatic string extraction has blind spots — interpolation, plurals, SwiftUI initializers, and the layout that breaks in German. Here's what still needs a human.
Swift Finally Lets You Put a Memberwise Init Where It Belongs
SE-0546 fixes a Swift limitation nearly a decade old: you couldn't define a struct's memberwise initializer in a same-file extension. Here's why that mattered, with a real example from a Live Activity.
Weak Self Isn't the Retain Cycle Fix You Think It Is in @Observable
The old [weak self] advice was written for closures capturing classes. @Observable changes what actually gets captured, and in a few common SwiftUI patterns weak self silently does nothing at all. Here's where it still matters and where it's dead weight.
SwiftUI Just Turned Seven. Hacker News Is Having the Itch.
SwiftUI shipped in 2019 and just hit its seven-year mark, and a viral Hacker News thread (plus pieces from Yakov Manshin and John Gruber) is relitigating whether it ever grew up. I've built a real app in it for months — here's where my own bugs match the complaints, and where they don't.
Apple Just Open-Sourced the 'Skills API' Everyone Assumed Was a Claude Thing
Apple's new foundation-models-utilities package brings a Skills API, history compaction, and a chat-completions bridge to Swift's Foundation Models framework. Here's what's actually in the box, and how it maps onto BrewLog.
I Tried the Library That Puts Foundation Models, OpenAI, and MLX Behind One Swift API
SwiftAI is a new open-source Swift package that wraps Apple's on-device Foundation Models, OpenAI, and MLX behind one interface — reply(to:), @Generable structs, streaming, tool calls. I actually installed it, ran real on-device inference, and hit a documentation bug and a guardrail glitch within ten minutes. Here's what works, what doesn't, and whether it's worth adopting today.
Your AI Agent Has Amnesia: Context Rot Is Why It Forgets Your Swift Codebase by Lunch
Context rot is the reason your coding agent starts brilliant and turns into a confidently-wrong intern two hours later. Chroma's study measured it across 18 models, it hits SwiftUI codebases hard, and the fix isn't a bigger context window — it's context engineering. Here's what actually works in Xcode 26.
UIKit Tricks SwiftUI Still Can't Do (Yet): Back to UIViewRepresentable
Day 28 of the 30-day iOS series. SwiftUI has no PDF viewer, no custom keyboard primitive, and no waterfall grid — five real gaps where you still reach for UIViewRepresentable, anchored by a real PDFKit-backed brew history export built TDD-first for BrewLog.
Combine in 2026: The Three Cases Where It's Still Better Than async/await
Day 27 of the 30-day iOS series. A real searchable brew history for BrewLog, built with Combine instead of async/await, and the three reasons it was the right call: debounce, independent multiple subscribers, and a four-way CombineLatest pipeline.
Live Activities and the Dynamic Island: A Decision Matrix, Not a Demo
Day 26 of the 30-day iOS series. A real ActivityKit countdown for BrewLog's pour-over timer, the one-function decision matrix that decides which brew methods even get one, and the exact reason it still won't show up on a Lock Screen.
WidgetKit and App Intents: Logging a Brew Without Opening the App
Day 25 of the 30-day iOS series. A real App Intent that logs a brew from Spotlight or a widget button, the @Dependency crash that nearly cost me an evening, and the honest line between what's tested and what's still a mechanical Xcode step.
TDD for SwiftUI: A Red-Green-Refactor Workflow That Isn't Academic
Day 21 of the 30-day iOS series. I went looking for a BrewLog feature to drive test-first and found a real bug already shipped: the Streak stat has been hardcoded to zero since day one. Here's the actual red-green-refactor session that fixed it.
Dependency Injection in Swift Without a Framework
Day 19 of the 30-day iOS series. Protocol-based DI, @Environment as a SwiftUI-native container, and the factory pattern — all without Resolver, Swinject, or any third-party glue. Includes a TDD example that shows why DI and testability are the same conversation.
StoreKit 2, Part 2: Free Trials, Win-Back Offers, and Promo Codes That Actually Convert
Day 16 of the 30-day iOS series. I add a 7-day free trial, a win-back banner for lapsed subscribers, and offer-code redemption to BrewLog's paywall — concrete App Store Connect configuration plus the Swift code, all covered by Swift Testing.
A StoreKit 2 Paywall From Scratch: Subscriptions, a Transaction Listener, and a Restore Button That Works
Day 15 of the 30-day iOS series, first of a three-part run on monetization. I built BrewLog's real paywall with StoreKit 2 — two subscription products, a transaction listener, and a restore flow — with zero third-party SDKs. Every number the paywall shows comes from one pure, tested function.
SwiftData Two Years Later: What's Solid, What Still Bites, and the Migration Test You're Not Writing
Day 14 of the 30-day iOS series. SwiftData is about two years old now, and the honest verdict is mixed. I already wrote the long field report on where it broke in production — this post is the part that report didn't have room for: a VersionedSchema + SchemaMigrationPlan test that proves a schema change is safe BEFORE TestFlight finds out for you.
@Observable vs ObservableObject: What 1,000 Rows and a Redraw Counter Actually Showed Me
Day 13 of the 30-day iOS series. I built a redraw counter into BrewLog, put 1,000 rows in two identical lists side by side — one backed by @Observable, one by ObservableObject — and toggled a single favorite ten times. The row counts tied 10-10. The list counts didn't. Here's the real number, and exactly where it comes from.
@State, @Bindable, @Environment: The Complete Map for @Observable (and the Question You're Actually Asking)
Day 12 of the 30-day iOS series. With @Observable, SwiftUI lets you slap @State, @Bindable, @Environment, or a plain let on the same class — and compiles all of them. Here's the question that actually decides which one is correct, one map that resolves 95% of the confusion, and three real BrewLog bugs (one silent, one a compile error, one a runtime crash) that come from picking wrong.
ObservableObject → @Observable: The Migration Guide That Skips the Marketing (and the Autoclosure Gotcha Apple Forgot to Mention)
Day 11 of the 30-day iOS series. Apple's migration guide makes ObservableObject → @Observable look like a find-and-replace. It mostly is — except for one quiet behavioral change: @StateObject only ran your initializer once, and @State runs it on every render. Here's the multiple-init bug that causes, why it's worst in exactly the init you were proud of, and how to fix it with a test that turns 'no side effects in init' into a hard, green invariant.
The Keynote Made You Cry. The State of the Union Gave You Homework. Five Things That Actually Change Your iOS Workflow.
WWDC 2026 State of the Union broke open the developer toolbox: free Private Cloud Compute for indie devs, Foundation Models going open source, Xcode 27's Device Hub killing Simulator, agentic coding with Claude and Gemini inside your IDE, and SwiftUI finally caching images like it should have from day one.
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.
Tim Cook Wiped a Tear, Siri Got a Google Brain, and Apple Shipped a Transparency Slider. WWDC 2026, Honestly.
The WWDC 2026 keynote just happened. Tim Cook's emotional farewell, Siri rebuilt on Gemini, Core AI replacing Core ML, Xcode 27 going full MCP, and Liquid Glass finally getting a slider. Here's what actually matters for your iOS codebase — no press release fluff.
@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.
Tim Cook's Curtain Call: His Last WWDC Keynote and What Changes for Every iOS Developer
Tim Cook delivers his final WWDC keynote on June 8 before handing the CEO role to hardware chief John Ternus on September 1. After 15 years, a $350B-to-$4T run, and a developer ecosystem of 2.3 billion devices, here's what the transition actually means for people who write Swift for a living.
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.
Apple Said 'All Systems Glow.' Developers Said 'Not So Fast.'
Apple dropped its WWDC 2026 tagline yesterday and the developer forums immediately caught fire. Half the community is excited for iOS 27's AI overhaul. The other half is already mourning the operating system they used to love. With six days until the keynote, here's what the divide tells us about where Apple is headed.
Your App Just Got an Eviction Notice: Liquid Glass Is Mandatory in iOS 27
Apple confirmed Liquid Glass is non-negotiable in Xcode 27. Your custom tab bars, navigation views, and carefully crafted layouts are about to meet a wrecking ball called UIDropShadowView. Here's exactly what breaks, what the timeline looks like, and how to survive the migration before WWDC drops on June 8.
Apple Is Turning Every App Into an AI Tool — MCP Support Means Siri Was Just the Warm-Up
Apple is building native Model Context Protocol support on top of App Intents. That means Claude, ChatGPT, Gemini, and every other AI agent will be able to control your app — not just Siri. Nine days before WWDC 2026, here's what this means for iOS developers and why your App Intents just became the most important code you've ever written.
Apple Registered genai.apple.com. Twelve Days Before WWDC, the Biggest Clue Just Dropped.
Apple quietly registered a GenAI subdomain last week. It's not live yet, but the timing — twelve days before WWDC 2026 — tells us everything about where the iOS developer platform is headed. Core AI, Siri Extensions, Foundation Models, and a public-facing AI hub. Here's what it means for your next project.
I Wrote Swift in Cursor for a Week. Xcode, We Need to Talk.
Swift officially hit the Open VSX Registry — meaning Cursor, Kiro, and every AI IDE now support Swift with full LSP, debugging, and test explorer. I spent a week building iOS code outside Xcode. Here's what worked, what didn't, and why Apple publishing a Cursor setup guide is the most understated power move of 2026.
Liquid Glass Turns One. We're Still Squinting.
Apple's Liquid Glass design language is celebrating its first birthday — and the party is divided. With WWDC 2026 two weeks away and iOS 27 doubling down, here's where things actually stand for developers: the wins, the accessibility mess, the adoption gap, and why your next SwiftUI update might need reading glasses.
Visual Intelligence Is the Sleeper Hit of WWDC 2026. Most Developers Don't See It Coming.
Apple is opening Visual Intelligence to third-party developers at WWDC 2026 — nutrition scanning, contact capture, Wallet passes, and a full camera AI pipeline. While everyone argues about Siri, this is the API that will actually change how your app works. Here's what we know and how to prepare.
WWDC 2026 Is 26 Days Away. This Is Your iOS Developer Pre-Flight Checklist.
WWDC 2026 lands June 8. SiriKit deprecation, Core AI replacing Core ML, Liquid Glass refinements, foldable iPhone APIs, and strict concurrency in Swift 7. Here's the practical pre-flight checklist to run through your codebase right now — before the keynote makes it urgent.
The App Store Just Had Its Biggest Quarter in History. Here's Why That's a Problem.
App Store submissions are up 80% on iOS. AI coding tools turned everyone into a developer overnight. But when 200,000 new apps hit the store every week, the question isn't whether you can build an app anymore — it's whether anyone will find it.
App Intents Are the New SEO — and Most iOS Developers Are Still Invisible
Siri is becoming the front door to every iPhone. App Intents are no longer a nice-to-have — they're the difference between discoverable and dead. Here's a practical guide to making your app visible before WWDC 2026 changes the rules.
I've Been Pair Programming With Xcode's AI Agent for 3 Months. We Need to Talk.
Xcode 26.3 shipped agentic coding with Claude and Codex in February. Three months later, here's what it's genuinely great at, where it falls apart, and why it made me rethink how I write SwiftUI code — for better and worse.
Swift 6.2 Finally Made Concurrency Approachable — Someone Already Built a Parody Site
Swift 6.2 ships @MainActor by default, the new @concurrent attribute, and a complete rethink of strict concurrency. We break down what changed, show real migration code, and explain why the community is both celebrating and arguing.
Claude Code vs Cursor: I Used Both for a Month. One Tried to Charge $1,400.
Cursor is the sous chef who hands you the knife before you ask. Claude Code is the contractor who remodels your kitchen overnight. We tested both on real iOS projects and here's when each one wins — plus how to avoid that terrifying billing surprise.
Swift 6.3 Now Officially Runs on Android. I Tried It. Here's What Actually Works.
Apple shipped an official Swift SDK for Android with Swift 6.3. Not a hack, not a community port — the real thing. We tested it on a real project and here's every win, every friction point, and the honest verdict on whether iOS developers should care.
We Updated Our App Icon for iOS 26. Apple Now Wants Three of Them. So We Built a Tool.
iOS 26 Liquid Glass quietly tripled the work to ship an app icon — default, tinted, and dark variants for every iPhone app. Existing icon tools haven't caught up. We hit the wall updating ThinkBud last week, so we built a free generator. Here's what changed in iOS 26, why every iOS dev is about to learn this the hard way, and the tool we shipped to handle it.
Apple's iOS 26 SDK Deadline Hits Tomorrow. Half the App Store Isn't Ready.
April 28, 2026 — every app submitted to the App Store must be built with Xcode 26 and the iOS 26 SDK. If you haven't updated yet, your next submission gets rejected. Here's what's breaking, what you need to fix, and why this deadline is different.
I Migrated Two Apps to SwiftData. Eighteen Months Later, I'm Migrating Half of It Back.
SwiftData turns three at WWDC 2026. After running it in production across two shipping iOS apps for a year and a half, here's an honest field report — what works, what quietly broke, and the three places we went back to Core Data and don't regret it.
We Gave Claude Mythos Full Access to Our Codebase. It Shipped Three Features Before Lunch.
After a week of security testing, we let Anthropic's most restricted AI model loose on real development work. It refactored our state management, found a memory leak we'd chased for months, and rewrote our networking layer across four apps. Week two was a different beast.
Apple Is Shipping Foldable iPhone APIs Before the Foldable iPhone. That's Either Genius or Chaos.
WWDC 2026 drops June 8. Apple is giving developers fold-state detection, Core AI replacing Core ML, macOS touch APIs, and a Siri that lives in the Dynamic Island. Here's what you need to know and what we're already building.
Apple Put a 3-Billion Parameter Brain Inside Every iPhone. Most Developers Haven't Even Noticed.
Apple's Foundation Models framework lets you run AI on-device with 3 lines of Swift. No API keys. No cloud bills. No privacy headaches. Here's why iOS developers should stop ignoring the smartest thing Apple shipped in years.
The iPhone Fold Ships in September. Your App Layout Just Had a Panic Attack.
Apple's foldable iPhone has entered trial production. A 7.76-inch inner display, book-style fold, and no Face ID. SwiftUI developers have a head start. UIKit holdouts should start stretching.
Apple Stopped Pretending It Could Build AI Alone. That's the Best WWDC News in Years.
WWDC 2026 is two months away. Apple is opening Siri to Claude, Gemini, and Grok. Xcode already has agentic coding. iOS 27 is a stability year. Here's what iOS developers actually need to care about.
Apple Gave iOS a Makeover Nobody Asked For. Now Everyone Has to Live With It.
Liquid Glass is permanent, expanding, and mandatory in iOS 27. Apple's VP of design left for Meta. Developers lost customization options. Users can't read their screens. And Apple just told everyone to deal with it.
Vibe Coding in iOS Development: A Comprehensive Analysis of AI Models, Tools, and Workflows
After months of testing every major AI model and coding tool for native iOS development — from OpenAI to Anthropic, Cursor to Claude Code — here is what actually works, what does not, and why Claude Opus 4.6 changed everything.
Why We Choose Native Over Cross-Platform
Our philosophy on building native Apple apps instead of using cross-platform frameworks, and why we believe native development leads to better user experiences.