swiftui · essay · architecture · security

Foundation Models and Feature Boundaries

Published September 7, 2026 · 3 min read · advanced

The confusion

AI features make it tempting to wire a new capability straight into the nearest view. The feature feels small at first, so people skip the architecture conversation.

That is usually where the problems start. Once a model call, prompt, or generated result is embedded too deep in the view tree, the app becomes hard to test, hard to explain, and hard to change.

What SwiftUI is actually doing

SwiftUI does not care whether the feature is powered by a local model, a remote model, or a human-authored fallback. It only cares about state, invalidation, and rendering.

That means AI features should still follow normal SwiftUI boundaries:

  • the view describes the result
  • a feature object owns the request lifecycle
  • the environment injects app-wide policy
  • side effects stay outside body

If an AI answer can fail, be delayed, or be replaced by a fallback, the boundary matters even more.

The mental model

AI features belong to the same architecture rules as every other feature: explicit ownership, explicit dependencies, explicit failure paths.

The model call is not the architecture. The architecture is the place where you decide:

  • who can trigger the request
  • where the result is cached
  • how errors are shown
  • what the fallback looks like

That is the part that keeps a “smart” feature from becoming a maintenance problem.

A small proof

import SwiftUI

struct SummaryScreen: View {
    @State private var summary: String = "Waiting for input..."

    var body: some View {
        VStack(alignment: .leading, spacing: 12) {
            Text(summary)
            Button("Regenerate") {
                Task {
                    summary = "Updated summary"
                }
            }
        }
        .padding()
    }
}

This example is intentionally simple. Even here, the important part is not the model output. It is the fact that the button triggers the work and the view only renders state. That separation scales much better than letting the request live inside body.

Why this matters in real apps

Foundation Models and related AI integrations are most useful when they stay composable. If a feature needs user consent, caching, logging, or a fallback for offline use, you want those choices in one place.

That also makes review easier. A reviewer can look at one feature boundary and answer:

  • where is the prompt built
  • where does the result land
  • how is it cancelled
  • what happens when the model is unavailable

That is much better than hunting through several nested views for hidden behavior.

Where this model breaks down

Not every AI-powered screen needs a separate service layer. Some very small interactions can stay local, especially if the result is transient and the failure mode is trivial.

But once you have retries, privacy concerns, or multiple entry points, the feature deserves its own boundary. At that point, the “just call it from the view” approach becomes a liability.

One sentence to remember

AI is a feature capability, not an excuse to abandon normal SwiftUI boundaries.

Next steps

These follow-ups keep the AI discussion anchored in the same ownership and side-effect discipline: