nativefirst.app
</>
NativeFirst Academy

Learn to Build
Native iOS Apps with AI

Hands-on courses that teach you how to build production-quality iOS apps using AI-powered development workflows.

Notes from the field. Mostly bruises.

Standalone iOS dev write-ups from shipped apps — concurrency migrations that bit us, SwiftData edges we found in TestFlight, the opinions you only earn by deploying. Not tutorials, not news. Just honest reports.

intermediate

App Intents + Spotlight Semantic Search — How I Doubled BetFree's Spotlight Opens in Two Weeks (and the Tests That Caught Three Bugs Before Shipping)

Post-series field note. iOS 26's Spotlight semantic index quietly became one of the highest-intent discovery surfaces on the phone — and most indie apps still treat it as an afterthought. This is the TDD-first walkthrough of indexing App Intents and CSSearchableItems on BetFree, the four bugs I caught with tests before they hit the App Store, and the WWDC 2026 surface area worth front-loading before June 8.

Read note
intermediate

Build-Time Optimization for a Solo Developer with Five Apps — The Numbers, the Setup, and the Habits That Cut My Cold Build From 142s to 38s

Day 30 of 30. The series finale. One developer, five shipping apps, one Mac Studio. This is the honest tour of my build-time setup in 2026: module isolation across SPM, prebuilt binary frameworks, derived-data hygiene, the Xcode 26 build-system improvements that actually moved the needle, and the four habits I had to break to stop shipping a slow build. Concrete numbers before and after, on real apps — Invoize, Renovise, ThinkBud, BetFree, and Reset — not synthetic benchmarks.

Read note
intermediate

Custom Swift Macros in 2026 — When They Are Actually Worth the Trouble (and a #URL Macro That Validates Links at Compile Time)

Day 29 of 30. Swift macros are the most over-recommended feature of the last three years. This post is the honest one: what @freestanding vs @attached actually means in practice, the four-question gate I run before writing one, the over-engineering trap that cost me a week on Renovise, and a real #URL(_:) macro that turns URL(string:)! into a compile-time error instead of a runtime crash — with TDD-first tests that pin the behavior, not the implementation.

Read note