Community-maintained Agent Skills for complete Swift and Apple-platform app delivery.
73
92%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Medium
Suggest reviewing before use
Adapted and rewritten for this collection; see ../NOTICE.md.
Review ownership and invalidation separately. @State, @Bindable, and
@Environment are not interchangeable wrappers, and a model being observable
does not make every nested reference observable.
@StateFor an @Observable reference type, @State is appropriate when the view owns
the model identity and its lifetime:
@Observable final class EditorModel {
var title = ""
}
struct EditorView: View {
@State private var model = EditorModel()
var body: some View { Text(model.title) }
}Do not claim that SwiftUI recreates the stored model on every body evaluation.
The view value and the state storage have different lifetimes. Instead, inspect
whether the initializer has expensive side effects, whether a parent should own
the identity, and whether a new input is being ignored because @State keeps
the first value.
A child that receives an existing model should not put it in @State merely to
make it available; that changes ownership and can preserve the first instance.
Use a plain property for read-only access, or @Bindable when controls need a
two-way binding:
struct EditView: View {
@Bindable var model: EditorModel
var body: some View {
TextField("Title", text: $model.title)
}
}For an environment-provided observable, read it with @Environment and create
a local bindable projection inside body:
struct SettingsView: View {
@Environment(AppSettings.self) private var settings
var body: some View {
@Bindable var settings = settings
Toggle("Dark Mode", isOn: $settings.darkMode)
}
}Mark a property @ObservationIgnored only when it should not participate in
view invalidation (for example, a logger, repository, or cache that is accessed
outside rendered state). Verify that ignored changes cannot affect what the view
renders. A property wrapper does not automatically make its wrapped value
observable.
If a model stores a reference whose mutable properties are read by a view, that nested reference should participate in Observation or explicitly publish changes through the owning model. Do not flag a nested type merely because it is not annotated: first check which properties the view reads and how mutations are propagated.
withObservationTracking invokes onChange when a tracked property is about to
change and the tracking registration is one-shot. Re-register tracking for
continued observation and schedule work on the actor that owns the model; do not
assume a global DispatchQueue.main hop is the correct fix.
| Combine-era pattern | Observation-era direction |
|---|---|
ObservableObject / @Published | @Observable and stored properties |
@StateObject | @State when the view owns the observable identity |
@ObservedObject | Plain property for reads, @Bindable for bindings |
@EnvironmentObject | @Environment(Type.self) for an injected observable |
Do not recommend migration just because a project uses Combine. Check deployment targets, existing publisher contracts, and whether the change is in scope.
@State preserving state intentionally, or hiding a parent-owned model?@Bindable, or is a read-only property enough?.tessl-plugin
skills
accessorysetupkit
references
activitykit
adattributionkit
references
alarmkit
references
app-clips
app-intents
app-store-optimization
app-store-review
apple-on-device-ai
appmigrationkit
audioaccessorykit
references
authentication
references
avkit
background-processing
references
browserenginekit
callkit
references
carplay
cloudkit
contacts-framework
references
core-bluetooth
references
core-data
core-motion
references
core-nfc
references
coreml
references
cryptokit
cryptotokenkit
references
debugging-instruments
device-integrity
references
dockkit
energykit
references
eventkit
financekit
references
focus-engine
gamekit
healthkit
references
homekit
references
ios-accessibility
ios-app-workflow
references
ios-ettrace-performance
ios-localization
ios-memgraph-analysis
ios-networking
ios-simulator
references
metrickit
references
musickit
references
natural-language
references
paperkit
references
passkit
references
pdfkit
pencilkit
references
permissionkit
references
photokit
push-notifications
realitykit
references
relevancekit
references
scenekit
sensorkit
speech-recognition
references
spritekit
storekit
swift-api-design-guidelines
swift-architecture
references
swift-charts
swift-codable
references
swift-code-review
swift-concurrency
swift-formatstyle
references
swift-language
swift-security
references
swift-testing
swiftdata
swiftlint
swiftui-animation
swiftui-gestures
references
swiftui-layout-components
swiftui-liquid-glass
references
swiftui-patterns
swiftui-performance
swiftui-responsive-layout
swiftui-uikit-interop
swiftui-webkit
tabletopkit
tipkit
vision-framework
weatherkit
references