पाठ 18 / 25

Property Wrappers, Result Builders and Macros

Recognise the language features behind SwiftUI and modern frameworks.

Features that power frameworks

Several advanced features let libraries create expressive APIs. Property wrappers (@propertyWrapper) package reusable storage logic: you write @Clamped(0...100) var volume = 50, and the wrapper's code runs on every get and set; SwiftUI's @State and @Binding and many persistence helpers are property wrappers. Result builders (@resultBuilder) transform a block of statements into a combined value, which is how SwiftUI's VStack { Text(...); Image(...) } syntax and many DSLs work. Macros (Swift 5.9+) generate code at compile time: freestanding macros such as #Preview, #expect and #URL-style helpers, and attached macros such as @Observable (Observation framework) and SwiftData's @Model, which add properties and conformances to your types. Macros are type-checked and expand to ordinary Swift you can inspect in Xcode with "Expand Macro". You will mostly use these features rather than write them, but understanding them removes the mystery from SwiftUI code.

A small property wrapper and an @Observable model

The wrapper clamps values; the macro generates observation code.

@propertyWrapper
struct Clamped<Value: Comparable> {
    private var value: Value
    private let range: ClosedRange<Value>

    init(wrappedValue: Value, _ range: ClosedRange<Value>) {
        self.range = range
        self.value = min(max(wrappedValue, range.lowerBound), range.upperBound)
    }

    var wrappedValue: Value {
        get { value }
        set { value = min(max(newValue, range.lowerBound), range.upperBound) }
    }
}

struct PlayerSettings {
    @Clamped(0...100) var volume = 50
}

var settings = PlayerSettings()
settings.volume = 140
print(settings.volume)            // 100

import Observation

@Observable                        // attached macro: generates change tracking
final class CartModel {
    var items: [String] = []
    var total: Double = 0
}

Expand macros when confused

In Xcode, right-click a macro such as @Observable and choose Expand Macro to see the generated code. It turns "magic" into ordinary Swift you can read.

त्वरित जाँच: Which Swift feature makes SwiftUI's declarative view syntax inside VStack { ... } possible?

  • Result builders
  • Property wrappers
  • Typed throws
  • Access control
Answer

Result builders — Result builders combine the statements in a closure into a single view value.