Swift Property Wrappers: Reusable Logic for Properties
A Swift Property Wrapper is a template for a property's get/set logic, letting you reuse behaviors like data validation without boilerplate. It powers SwiftUI's @State and is great for managing UserDefaults.
Why it exists
Many properties share common implementation patterns, like being lazy, thread-safe, or persisted to user defaults. Before property wrappers, Swift hardcoded a few of these (like lazy), but developers had to write repetitive boilerplate for their own custom patterns. Property wrappers provide a general, reusable way to define this logic once and apply it anywhere.
The mental model
A Property Wrapper is a separate type that manages a property's storage and access. Think of it as delegating a property's implementation. When you write @UserDefault(key: "hasSeenOnboarding") var hasSeenOnboarding: Bool, you're telling the compiler to use the UserDefault wrapper's logic to handle getting and setting the hasSeenOnboarding boolean, instead of just storing it in memory.
How it works
A type becomes a property wrapper by being marked with the @propertyWrapper attribute and implementing a wrappedValue property. The compiler then rewrites access to the property you've decorated. A call to myProperty is translated into a call to _myProperty.wrappedValue, where _myProperty is the hidden, compiler-synthesized instance of the wrapper type. A wrapper can also provide a projectedValue, accessed with a dollar sign prefix (e.g., $myProperty), to expose additional functionality, like the binding from a SwiftUI @State property.
When to use it
Use property wrappers to eliminate boilerplate for recurring property logic. Three key places this shines: first, managing state, which is the foundation of SwiftUI (@State, @Binding, @Environment); second, abstracting storage, like reading/writing from UserDefaults or a database; and third, enforcing constraints, such as clamping a number within a range or ensuring a string is always lowercase.
When not to use it
Avoid property wrappers for logic that is unique to a single property, as the added abstraction isn't worth the complexity. If the logic is simple and doesn't need to be reused, a standard computed property with a getter and setter is often clearer. For simple stored values with no special behavior, a wrapper is just unnecessary overhead.
One canonical example
SwiftUI's @State is a property wrapper. When you declare @State private var tapCount = 0, you're not just creating an integer. You're creating an instance of the State struct, which holds your integer. The wrappedValue gives you direct access to the tapCount integer. The projectedValue (accessed via $tapCount) gives you a Binding, which you can pass to child views so they can also read and write the value, triggering UI updates automatically.
Interview question
For which scenario would a Swift property wrapper be the most appropriate choice over a standard computed property?
- a.To encapsulate and reuse a common pattern of access or storage logic across multiple properties.Correct
- b.To implement highly specific and complex logic that applies to only one unique property.
- c.To define a property whose value is always calculated dynamically from other properties.
- d.To store a simple value directly in memory without any additional behavior or validation.
Why? this is the answer
Property wrappers are specifically designed to eliminate boilerplate by allowing you to define and reuse common property logic, such as validation or persistence, across multiple properties. Option C describes a primary use case for a standard computed property, not a property wrapper's unique advantage.
Just read this? Test yourself on what you have been reading.
Read the original → github.com
- #swift
- #ios
- #patterns
- #api design
Put your scrolling time to good use
Learn one idea, try a quiz and save useful cards for revision. Tezvyn makes it easy to learn and stay current in your tech field, a few minutes at a time.
The iPhone app is on the way
We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.
Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.
We are hiring for this. Open roles that interview on swift — each one lists the topics its interview covers.
See open roles