TipKit in the wild: A/B results from two feature-discovery scenarios
I skipped TipKit in the iOS 17 beta and picked it up seriously with 17.1, rolling it out in two projects. It’s…
Subscription groups and family sharing: how I wire them across 3 apps
I support family sharing across three of my apps. Ticking the box in App Store Connect is not enough, you also need…
StoreKit 2 promotional offers: the setup that cut churn by 12 points
Two years of subscription data showed a pattern I couldn’t ignore: churn spiked hard on day 90. I had no pause or…
PhotosUI picker vs PhotoKit: picking the right one
When iOS 14 brought PhotosUI, I thought I was done with PhotoKit. Three projects in, the tradeoffs are clear: both have a…
Share Extension memory limits: the numbers Apple won’t print
Share Extension is one of the most memory-constrained extensions on iOS. Apple’s docs say “limited” and stop there, without real numbers. I…
Background URLSession: making 2 GB uploads actually reliable
One of my apps lets users upload 1 to 2 GB video files. The upload has to keep going when WiFi drops,…
Keychain Services thread safety: three race conditions I’ve hit
Keychain Services is documented as thread-safe. In theory, yes. In practice, concurrent access patterns gave me results I didn’t expect. Here are…
Local notifications: the 100% delivery myth
Local notifications get sold as one of iOS’s simplest APIs. You say “remind the user at 14:00”, the system reminds them. On…
Core Data to SwiftData: lessons from an 18k MAU migration
I moved an 18k monthly active users todo app from Core Data to SwiftData. Today 92% of traffic runs through SwiftData, the…
AVFoundation audio recording: three pitfalls that only show in the background
I built an iOS voice-note app. AVFoundation’s recording API looks straightforward in the docs. On a real device, background, interruptions, and mix…
App Intents and Shortcuts: putting actions in the user’s hand
I’ve shipped App Intents on three projects. Done right, users get their job done without opening the app, triggered from the Shortcuts…
Observation framework: when I stopped reaching for @Published
I started 2025 with a greenfield project built on the iOS 17 Observation framework. Here’s what reaching for @Observable over ObservableObject and…