Delegate to the OS AI or Own It: Drawing the iOS 27 Feature Boundary
WWDC 2026 put AI into the OS core. Which app features should you hand to the OS AI, and which should you own? A boundary you will not regret, for indie developers.
WWDC 2026 has wrapped, and the theme was clear: AI is now a core OS feature. The revamped Siri is Gemini-based, and Apple Foundation Models opened for free to developers under two million first downloads. Apple also showed a path to call Claude or Gemini server-side from the same Swift API.
For an indie developer, this is a tailwind. Summarization and classification I used to implement against paid APIs may now arrive as a free OS feature. As a personal developer who has run wallpaper and relaxation apps for years, deciding how much AI to own myself has always been a recurring headache.
But pushing everything onto the OS is a risky call. Behind the convenience, you quietly lose differentiation and portability. This article draws the boundary between what to delegate to the OS AI and what to keep, in a form you will not regret.
First, view features in three layers
Talking about app AI as one lump leads to bad decisions. I think in three layers.
The first is generic processing that forms the foundation of the experience: text summarization, language detection, simple classification, input completion. These are table stakes, and no differentiation happens here.
The second is the app's personality itself. In my relaxation app, that means how words are chosen to match a user's mood, and how tone is tuned to the world the app builds. This is the core of the app's value.
The third is decision logic tied directly to revenue and retention: when to surface a purchase prompt, which content to push. Data and business judgment are entangled here.
These three layers reach very different conclusions about whether to delegate.
Four questions that decide delegate vs. own
Once the layers are split, ask each feature these four. I judge in this order.
Does this feature drive differentiation? If not, delegate to the OS and skip the work
What would the API cost if you owned it? If the OS free tier is enough, that is a strong reason to delegate
If the OS changes its spec, will users churn? If churn hurts, keep it in your hands
Will you ship on Android too? If a shared experience is required, insert your own abstraction layer
If the first answer is "no" and the other three are low-risk, delegate without hesitation. But if the first is "yes," owning it is safer even when the OS option is free. Holding your app's personality hostage to an OS behavior change is the thing I most want to avoid in long-term operation.
✦
Thank you for reading this far.
Continue Reading
What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.
WHAT YOU'LL LEARN
✦A 4-question table to sort delegate-vs-build by differentiation, cost, churn risk, and portability
✦Why the 'under 2M first downloads' free tier line genuinely helps indie developers
✦The classic way leaning on the OS AI bites you a year later, and how to avoid it
Secure payment via Stripe · Cancel anytime
✦
Unlock This Article
Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.
Run the four questions against a real feature list
Kept abstract, judgment stays dull. Let me run the questions against actual features from the relaxation app I operate.
Language detection on input text: no differentiation / small to own, but the OS free tier covers it / display does not wobble when the OS changes / Android has a standard API too. Verdict: delegate. Nothing to agonize over.
Word choice tuned to a user's mood: the core of differentiation itself / moderate cost / change this and the app experience breaks / the same feel is needed on both OSes. Verdict: own. Free or not, I do not hand it to the OS.
Timing of when to surface a purchase prompt: tied to revenue / no API needed since it is my own logic / behavior shifting on the OS's terms is out of the question / inseparable from business data. Verdict: own. It never even reaches the delegation list.
Lined up, only the middle layer, processing tied to personality, actually splits the decision. Foundation delegates, revenue stays owned. Those two decide almost automatically. Spend your deliberation on the middle layer.
Why the free-tier line actually helps
The free release came with an "under two million first downloads" condition. That is a welcome line drawn squarely around indie developers.
My apps add up to large totals across the catalog, but a new app's first downloads naturally sit inside that tier. The cost of trying an AI feature in a new app effectively drops to zero. Before, "I can't tell if the API cost pays back, so I'll skip the AI feature" was a normal decision. Removing that constraint matters.
There is a trap, though. The moment an app grows past two million, it falls out of the free tier. If you designed around deep dependence on the OS AI just because it was free, your cost structure breaks the instant you succeed. So treat the free tier as an entry point for trying things, and I recommend wiring a switch path to a paid API for revenue-bearing layers from the start.
See the break-even of delegation in rough numbers
Backing the call with numbers cuts hesitation. Take summarization, and roughly estimate the cost gap between owning the API and delegating to the OS.
Say one summary uses about 1,000 tokens in and out combined, and an external API costs about 0.2 cents per 1,000 tokens. A feature called 100,000 times a month runs roughly 200 dollars a month. If that fits inside the OS free tier, it all evaporates. For a new indie app, erasing a couple hundred dollars of fixed cost is not trivial, and it bites hardest before ad revenue ramps up.
Conversely, a feature called only 1,000 times a month costs around 2 dollars in API fees. At that scale, paying 2 dollars to build freely with a paid API beats carrying the constraint of OS dependence for a free tier. Pinching 2 dollars and pawning your personality to the OS does not add up.
The upside of delegation is largest for high-volume foundation processing and smallest for low-volume, personality-bearing processing. The numbers make that trend plain. So I prioritize delegating the costly, high-frequency processing first, and keep the low-volume, personality-related processing in my own hands. Adding this "call frequency x unit price" yardstick to the four questions makes the call even steadier.
How leaning on the OS bites you a year later
From my own experience and others' cases, the shape of regret is fairly fixed.
// Regret pattern: embed the OS AI directly in the UIfunc summarize(_ text: String) async -> String { // The screen is wired straight to the OS behavior and output format let result = await SystemLanguageModel.default.summarize(text) return result.text // breaks when the spec changes}
This works, but the UI is wired straight to the OS output format. When the next iOS changes summary length or formatting, your layout breaks. I made a similar mistake on another feature and ended up with a display that wobbled at every OS update.
The fix is to insert one thin boundary.
// Even when delegating, receive into your own domain typeprotocol SummaryProvider { func summary(of text: String) async throws -> Summary}struct Summary { // a stable type your app defines let headline: String let body: String}// Hide the OS implementation behind this. Swaps and Android support happen only herestruct OSFoundationProvider: SummaryProvider { /* ... */ }struct RemoteAPIProvider: SummaryProvider { /* ... */ }
Receive into your own words, SummaryProvider, and the screen never needs to know whether the backend is the OS or a paid API. Delegate, but hide the dependency. That single layer confines OS spec changes and Android rollout to one place.
Confirm the boundary works with a swap test
Once you insert a boundary like SummaryProvider, confirm it actually works. The check is simple: prove with a test that swapping the OS implementation for another changes nothing on screen.
// A stub for tests. Depends on neither the OS nor an APIstruct StubSummaryProvider: SummaryProvider { func summary(of text: String) async throws -> Summary { Summary(headline: "Test headline", body: "Test body") }}// Guarantee the screen logic knows nothing about the provider's internalsfunc test_summaryView_doesNotDependOnBackend() async throws { let provider: SummaryProvider = StubSummaryProvider() let summary = try await provider.summary(of: "any input") #expect(summary.headline == "Test headline") // No OS-specific type appearing here is proof the boundary holds}
If this test passes without touching a single OS type, the boundary is working. Conversely, if writing the test forces you to reach for an OS-specific type, that is a sign the dependency has leaked all the way to the screen. I use "can I write this test?" as the cheapest yardstick for the boundary's health. Whether a design is right shows up in whether you can swap it out.
If Android is in view, when do you insert the abstraction
If you stay iOS-only, keep the boundary minimal. But if there is any chance you ship on Android later, the call changes.
The hard part is timing. Build a thick abstraction up front for both OSes, and you carry waste if it ends iOS-only. Try to insert it later, and the OS types have already bled across the screen, making them painful to peel off.
My call is a two-stage one: receive only the differentiating processing into my own domain type from the start, and add abstraction to foundation processing the moment I commit to Android. Protect just the core, and the porting decision can wait. Trying to make every feature cross-platform from day one, only to slip the release, is the worse trade for an indie developer.
A realistic landing spot for indie developers
Abstracting everything is also overkill. Drawing careful boundaries around foundation work like text summarization stalls development. My landing spot is this.
Foundation processing that does not drive differentiation: thin boundary, delegate directly to the OS. Processing tied to the app's personality: always receive into your own domain type and hide the backend. Decisions tied to revenue: never hand them to the OS AI; keep them in your own data and logic.
This three-tier stance balances convenience and portability. Ride the OS evolution while keeping the app's core in your own hands. That is my boundary line for staying in the indie game for the long run.
To start, write your app's AI features on paper and run each through those four questions. What you can safely delegate and what you must keep will separate with surprising clarity.
Share
Thank You for Reading
Antigravity Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.