Property Wrappers
A property wrapper is reusable magic you attach above a property to automatically add extra behavior every time it's read or written.
Defining a Simple Property Wrapper
A property wrapper struct implements wrappedValue, and any logic placed inside its getter and setter runs automatically whenever the wrapped property is accessed.
Example: Defining a Simple Property Wrapper
@propertyWrapper
struct Clamped {
private var value: Int
private let range: ClosedRange<Int>
init(wrappedValue: Int, _ range: ClosedRange<Int>) {
self.range = range
self.value = min(max(wrappedValue, range.lowerBound), range.upperBound)
}
var wrappedValue: Int {
get { value }
set { value = min(max(newValue, range.lowerBound), range.upperBound) }
}
}
struct Settings {
@Clamped(0...100) var volume: Int = 50
}
var settings = Settings()
settings.volume = 150
print(settings.volume)
Login to try C/C++/Java/PHP code in the editor
Using a Property Wrapper on Multiple Properties
Once defined, a property wrapper can be reused on any number of properties across different types, applying its behavior consistently everywhere.
Example: Using a Property Wrapper on Multiple Properties
@propertyWrapper
struct Clamped {
private var value: Int
private let range: ClosedRange<Int>
init(wrappedValue: Int, _ range: ClosedRange<Int>) {
self.range = range
self.value = min(max(wrappedValue, range.lowerBound), range.upperBound)
}
var wrappedValue: Int {
get { value }
set { value = min(max(newValue, range.lowerBound), range.upperBound) }
}
}
struct GameCharacter {
@Clamped(0...100) var health: Int = 100
@Clamped(0...10) var level: Int = 1
}
var hero = GameCharacter()
hero.health = -20
hero.level = 99
print("Health: \(hero.health), Level: \(hero.level)")
Login to try C/C++/Java/PHP code in the editor
Common Mistakes
- Forgetting a property wrapper type must declare a
wrappedValueproperty; that's the required contract the@attribute relies on. - Confusing the wrapped value (accessed normally by name) with the wrapper instance itself (accessed with a leading
$, called the projected value). - Applying a property wrapper to a computed property; wrappers only apply to stored properties.
Chapter Summary
@propertyWrappermarks a struct or class as a reusable property wrapper.- The wrapper must expose a
wrappedValueproperty that Swift uses transparently. - Applying
@WrapperNameabove a property automatically routes access through the wrapper. - A
projectedValue(accessed with$name) can expose the wrapper itself for more advanced use.
🔒
Chapter Quiz — Complete all 7 topics to unlock
0/7 topics done
Complete these topics first: