Modern Swift
Focused reference for Swift language features that are commonly misused or
forgotten but are not concurrency-related. Concurrency lives in the
swift-concurrency skill; this skill deliberately does not duplicate it.
When to load which reference
| Topic | File | Load when |
|---|---|---|
@available, #available, deprecation, renames |
references/attributes.md#availability |
Marking API availability, deprecating, renaming, or gating runtime behavior on OS version |
@discardableResult |
references/attributes.md#discardableresult |
Function returns a value callers may reasonably ignore |
@frozen |
references/attributes.md#frozen |
Library author deciding whether an enum/struct layout is stable |
@inlinable, @usableFromInline |
references/attributes.md#inlinable |
Performance-critical code in a resilient library |
@backDeployed |
references/attributes.md#backdeployed |
Shipping a new API to clients running older OSes |
@resultBuilder |
references/attributes.md#resultbuilder |
Building a DSL (SwiftUI-style) |
@propertyWrapper |
references/attributes.md#propertywrapper |
Encapsulating get/set behavior on stored properties |
#Preview |
references/macros.md#preview |
Writing SwiftUI previews |
| Custom macros | references/macros.md#custom-macros |
Understanding or authoring Swift macros |
Routing guardrails
- Concurrency topics (
async,await,actor,@MainActor,Sendable,@Observable,@preconcurrency) belong to swift-concurrency. Do not answer them from this skill - defer. @frozen,@inlinable,@backDeployedare relevant only to resilient libraries (frameworks distributed as binaries with ABI stability). App targets rarely need them. If the user is writing an app, say so and suggest the simpler alternative.@backDeployedhas real rules beyond "copy the body": public or@usableFromInline, body must follow@inlinablerestrictions, methods on classes must befinal, stored properties are excluded. Seereferences/attributes.md#backdeployed.
Common mistakes
- Using
@frozenin an app target. It's a library-evolution feature and has no effect outside resilient libraries. Remove it. @backDeployedon a stored property. Not supported. Only computed properties (no storage), functions,finalmethods, and subscripts.@inlinablebody referencing aninternalsymbol. The body is emitted into client binaries, so it can only reference public or@usableFromInlinesymbols.- Forgetting
@discardableResulton a fluent API. Causes "result unused" warnings for legitimate call sites. Mark the method, don't tell the caller to add_ =. - Property wrapper with
didSetclamping loop. Swift prevents the recursion, but it's still clearer to clamp in the setter of a computedwrappedValuebacked by a private stored value. See the canonical pattern inreferences/attributes.md#propertywrapper.