Blog
Thoughts on iOS development, Swift, and building great mobile experiences.
Image loading on iOS: caching, decoding, and the mistakes that make scrolling worse
A practical image-loading setup for iOS: cache the right thing, decode off the main thread, control request churn, and stop blaming scrolling jank on the collection view.
Building a SwiftUI design system without overengineering it
A useful SwiftUI design system is not a giant abstraction layer. It is a small set of tokens, components, and rules that make product work faster without hiding the platform or freezing the app in theory.
Deep links on iOS: a setup that stays maintainable
A maintainable deep-linking setup comes from one rule: treat links as app routes with typed parsing, ownership boundaries, and tests, not as random URL handling scattered across the codebase.
Snapshot testing in 2026: when it helps, when it lies, how to keep it sane
Snapshot tests are useful when they protect stable UI or serialization contracts, but they become expensive noise the moment they start standing in for design review, product judgment, or weak lower-level tests.
Modern iOS testing stack: fast unit tests + stable UI tests + strategy
A useful iOS testing stack is less about tool choice and more about test boundaries, promotion rules, and keeping slow checks rare enough that people still trust the signal.
Feature flags: safe rollouts without shipping fear
A practical feature flag setup for iOS: separate release, experiment, and kill-switch flags, keep evaluation deterministic, and avoid the cleanup debt that turns rollout safety into product entropy.
Background tasks in 2026: what works, what gets throttled, and how to be reliable
A practical guide to background work on iOS in 2026: where BGTaskScheduler helps, where the system throttles you, and how to design refresh and processing flows that stay reliable on real devices.
Sendable pitfalls: what actually breaks, and how to redesign safely
Swift 6 surfaces Sendable problems exactly where values cross isolation boundaries. Here is what usually breaks, how to classify each error, and how to redesign ownership without hiding the problem behind @unchecked Sendable.
Actors in practice: safe shared state without "actor everywhere" nonsense
A practical guide to Swift actors: where they help, where they hurt, and how to isolate shared state without turning your app into async soup.
Swift 6 strict concurrency migration: the staged plan that won’t brick your app
A practical migration plan for Swift 6 strict concurrency: baseline warnings, isolate boundaries, fix Sendable issues, and tighten checks without stalling delivery.
SwiftUI lists that don’t lag: identity, diffing, and avoiding layout thrash
Most SwiftUI list “performance problems” are self-inflicted: unstable identity, accidental view churn, and heavy layout work in rows. Here’s how to make lists fast, measurable, and boring.
AGENTS.md for iOS: guardrails that stop AI from breaking your app
Treat AI as a powerful, unreliable teammate. An AGENTS.md file gives it constraints, workflows, and verification steps that keep your iOS codebase stable and your PRs reviewable.
Slash commands that save hours: /build /test /perf /release-notes for iOS
Turn repetitive iOS workflows into reliable one-liners. Define a small set of slash commands that run the right builds, tests, and checks, and generate release notes without ceremony.
Codex workflow for iOS: guardrails, repeatable loops, and how to keep the build green
A practical Codex-assisted workflow for iOS teams: define guardrails, run tight build and test loops, measure impact, and ship changes without breaking CI.
Networking in modern iOS: typed endpoints, retries/backoff, and observability without bloat
A practical URLSession setup that scales: typed endpoints and decoding, retry rules that do not create duplicate side effects, and lightweight logging/metrics so you can measure reliability and latency.
Modern iOS testing stack: fast unit tests + UI tests that don’t flake
A pragmatic iOS testing setup: keep unit tests fast, make UI tests stable, and add one verification loop that catches regressions without turning CI into a lottery.
App launch performance in 2026: first-frame thinking, cold-start budgets, and practical fixes
A practical way to measure iOS cold start and ship improvements: define a first-frame budget, diagnose the common failure modes, and verify changes with repeatable runs.
StoreKit subscriptions in the real world: entitlements, edge cases, and recovery strategies
A practical StoreKit 2 approach for subscription gating that survives renewals, grace periods, restores, and the weird stuff you only see after launch.
SwiftUI animations that don’t glitch: transactions, explicit vs implicit, and performance-safe patterns
A practical SwiftUI animation guide: how transactions actually work, why animations disappear, and how to ship smooth UI without expensive re-renders.
SwiftUI Observation performance: stop unwanted re-renders and measure what matters
Practical patterns for @Observable, avoiding accidental invalidations, and proving performance wins with measurement (not vibes).
Swift Concurrency in Practice: Async/Await and Actors
Practical Swift concurrency patterns for async/await, actors, MainActor, Sendable, cancellation, and building responsive iOS apps without data races.