This is Swift · medium, lesson 1: Property wrappers. Read the teaching and the stills before the checks. The quizzes are open book and test the subject — Swift itself — not product rules or layout trivia.
Swift Medium · Lesson 1 · On the house
Property wrappers
@propertyWrapper, wrappedValue, projectedValue sketch. Lesson 1 is free — on the house.
Lessons · Swift Medium · Lesson 1 of 10 · On the house
Property wrappers
@propertyWrapper, wrappedValue, projectedValue sketch.

You already know Introductory and Easy. Medium assumes those habits and asks for sharper tools.
A property wrapper is a type marked @propertyWrapper that wraps storage and intercepts get/set of a property. The essential stored piece is wrappedValue.
You apply a wrapper with @WrapperName on a property: @Clamped var score: Int. The compiler synthesizes storage of the wrapper type and forwards reads/writes through wrappedValue.
projectedValue is an optional second surface, usually exposed as $propertyName. Many wrappers project a publisher, binding, or the wrapper instance itself — the still keeps it small and explicit.
Wrappers can take init arguments via attributes: @Clamped(min: 0, max: 100) var score. Those arguments feed the wrapper's initializer before the wrapped value is set.
Composition is real: stacking wrappers nests them. Read the outermost attribute first when tracing get/set order. Prefer one clear wrapper over a stack you cannot explain.
SwiftUI's @State, @Binding, and friends are property wrappers — Medium teaches the mechanism so those feel less magical. You do not need UIKit or SwiftUI running to understand wrappedValue.
Misses: forgetting wrappedValue, treating $name as a second stored Int instead of the projection, or assuming every wrapper must project — projectedValue is optional.
Put Property wrappers in a sentence you could teach a friend: what changes, what stays the same, and what you expect from the still.
Change one dial at a time when you experiment, then re-run. Batch changes invent ghost bugs.
Predict the still on paper before you type. Prediction turns running into confirmation.
Name each token in the still aloud. Hesitation marks the exact gap.
When something fails, read the last error line first. Calm retries beat rewriting everything.
property-wrapper
@propertyWrapper
struct Clamped {
private var value: Int
private let min: Int
private let max: Int
var wrappedValue: Int {
get { value }
set { value = Swift.max(min, Swift.min(max, newValue)) }
}
var projectedValue: Int { wrappedValue }
init(wrappedValue: Int, min: Int, max: Int) {
self.min = min
self.max = max
self.value = Swift.max(min, Swift.min(max, wrappedValue))
}
}
struct Card {
@Clamped(min: 0, max: 10) var rank: Int = 0
}
var c = Card(rank: 12)
print(c.rank, c.$rank)
c.rank = -3
print(c.rank)Sit with that still. Trace it top to bottom. Name each piece. The exercise asks you to match its essence.
If something fails when you try it yourself, change one thing. Read the error. Return to the still. I will not rush you.
Quiz
What must a @propertyWrapper type provide?
Quiz
@Clamped var rank means?
Quiz
projectedValue is typically accessed as?
Quiz
Is projectedValue required on every wrapper?
Quiz
Wrapper init args in the attribute do what?
Quiz
After @Clamped(min:0,max:10) and rank=12, wrapped rank is?
Quiz
Based on today's teaching, which claim is right?
Check
Match the still for: Property wrappers.
That is the lesson. When every quiz and exercise on this page is green, mark it passed. Next lesson when you are ready.
Open-book: the answers are on this page. Pass every quiz and check (8) to mark the lesson done. This visit: 0/8.