swiftui · note · architecture · state
Observation Migration Checklist
Context
When you migrate a screen to @Observable, the code usually gets shorter fast.
That is nice, but it can also hide a common mistake: letting the new syntax blur the same old ownership boundaries.
This checklist keeps the migration focused on the right questions.
The snippet
@Observable
final class DraftProfile {
var name = ""
}
struct ProfileScreen: View {
@State private var draft = DraftProfile()
}
Why this works
This pattern works because ownership stays obvious.
The screen owns the draft with @State, and child views can borrow editing access with @Bindable when needed.
Observation then handles invalidation for you, but it does not decide who creates the model or who should keep it alive.
Use this checklist during migration:
- replace
ObservableObjectand@Publishedwith@Observable - keep model creation at the screen or feature boundary
- use
@Bindableonly in children that truly edit data - keep read-only subviews free of bindings
- re-check previews after every wrapper swap
The last item matters because previews are where accidental ownership leaks show up first.
Use it when…
- a screen already works but uses Combine-era observation
- a child needs to edit parent-owned data
- you want to reduce wrapper noise without changing behavior
Avoid it when…
- the model is still being shared as a global bucket
- the child only needs to display data
- you are migrating multiple ownership boundaries at once
Takeaway: Migration should simplify observation, not hide responsibility.