Property wrappers

Swift language Mid-level Swift 5.1+ iOS 17+ Reviewed By Alok Singh

Fill the blank

Fill the blank so @Clamped(0...10) var volume = 15 stores 10.

@propertyWrapper
struct Clamped {
    private var value: Int
    let range: ClosedRange<Int>
    var ____: Int {
        get { value }
        set { value = min(max(newValue, range.lowerBound), range.upperBound) }
    }
    init(wrappedValue: Int, _ range: ClosedRange<Int>) {
        self.range = range
        value = min(max(wrappedValue, range.lowerBound), range.upperBound)
    }
}
Options
Hint 1 of 1

Which property does @propertyWrapper require?

Choose an answer, then open Show answer below to check it.

Show answer

Answer: A wrappedValue

Correct. It is the required property every wrapper provides.

Why not the others?
  • B projectedValue. That is the optional $ projection, not the main value.
  • C value. value is already the private storage.
  • D storage. The compiler looks for a property named wrappedValue.

30-second answer

A property wrapper is a type marked @propertyWrapper with a wrappedValue that adds logic around a property's get and set, such as clamping, persistence or thread confinement. @State, @AppStorage and @Published are wrappers. A projectedValue is exposed with $.

Practise saying it · 30 s. No recording, just a timer

Explain property wrappers.

Say your answer out loud, then check which of these points you covered:

  • wrappedValue required
  • projectedValue via $
  • Examples: @State, @AppStorage

Deep dive

The initializer init(wrappedValue:) lets you write @Clamped(0...10) var volume = 5.

Wrappers can't be used on computed properties or in protocols.

Wrapped local variables are allowed (Swift 5.4+).

Macros now cover many cases wrappers were stretched to fill.

Common mistakes

  • Hiding expensive work in a wrapper.
  • Confusing @Observable (a macro) with a property wrapper.

Senior take & follow-ups

Seniors know the wrappedValue/projectedValue contract and when a macro fits better.

Follow-up questions

Think of your answer first, then open the hint.

  1. What is projectedValue for?

    Show hint

    Extra API exposed through $, like Binding.

  2. When would you choose a macro instead?

    Show hint

    When you need to generate code across a whole type.

Suggest a fix if something here is wrong or out of date.