📖 Scenario: You are building a simple user profile system where you want to control how the user's age is stored and validated.
🎯 Goal: Create a @propertyWrapper called AgeLimit that ensures the age is always between 0 and 120. Then use it in a User struct to store the user's age safely.
📋 What You'll Learn
Create a @propertyWrapper named AgeLimit
Inside AgeLimit, have a private variable value of type Int
Initialize value with a default age passed in the initializer
Clamp the age value between 0 and 120 in the wrappedValue property
Create a struct User with a property age using the @AgeLimit wrapper
Initialize a User instance with an age and print the age
💡 Why This Matters
🌍 Real World
Property wrappers help keep data clean and safe by controlling how values are stored and changed, useful in apps with user input.
💼 Career
Understanding property wrappers is important for Swift developers to write clean, reusable, and safe code in iOS and macOS apps.
Progress0 / 4 steps
1
Create the @propertyWrapper AgeLimit with a private value
Create a @propertyWrapper named AgeLimit with a private variable value of type Int initialized to 0.
Swift
Hint
Use @propertyWrapper before the struct declaration. Inside, declare private var value: Int = 0.
2
Add initializer to AgeLimit to set initial age value
Add an initializer to AgeLimit that takes an Int parameter called wrappedValue and sets value to it.
Swift
Hint
Write init(wrappedValue: Int) and assign wrappedValue to value.
3
Implement wrappedValue property to clamp age between 0 and 120
Add a computed property wrappedValue of type Int that returns value clamped between 0 and 120. When setting, update value with the clamped new value.
Swift
Hint
Use a computed property with get and set. Clamp values using conditional expressions.
4
Create User struct using @AgeLimit and print age
Create a struct User with a property age using the @AgeLimit wrapper. Initialize a User instance with age 150 and print user.age.
Swift
Hint
Define User with @AgeLimit var age: Int. Create user with age 150 and print user.age.
Practice
(1/5)
1. What is the main purpose of using @propertyWrapper in Swift?
easy
A. To define functions that run asynchronously
B. To create new data types like classes or structs
C. To add reusable behavior to variables by controlling their access and storage
D. To handle errors in Swift code
Solution
Step 1: Understand what @propertyWrapper does
@propertyWrapper is used to add reusable behavior to variables, such as validation or transformation, by controlling how their values are stored and accessed.
Step 2: Compare with other options
Options B, C, and D describe unrelated Swift features: defining types, async functions, and error handling, which are not the purpose of @propertyWrapper.
Final Answer:
To add reusable behavior to variables by controlling their access and storage -> Option C
Confusing @propertyWrapper with class or struct definitions
Thinking it handles async code or errors
Believing it creates new data types
2. Which of the following is the correct minimal syntax to declare a property wrapper named Capitalized?
easy
A. @propertyWrapper struct Capitalized { var wrappedValue: String }
B. struct Capitalized { @propertyWrapper var wrappedValue: String }
C. struct Capitalized { var wrappedValue: String }
D. @propertyWrapper var Capitalized: String
Solution
Step 1: Recall the syntax for declaring a property wrapper
A property wrapper must be declared as a struct or class with the @propertyWrapper attribute before its definition, and it must have a wrappedValue property.
Step 2: Analyze each option
struct Capitalized { var wrappedValue: String } misses the @propertyWrapper attribute. @propertyWrapper struct Capitalized { var wrappedValue: String } correctly uses @propertyWrapper before the struct and defines wrappedValue. struct Capitalized { @propertyWrapper var wrappedValue: String } incorrectly places @propertyWrapper before the property, which is invalid. @propertyWrapper var Capitalized: String tries to declare a variable with @propertyWrapper, which is incorrect syntax.
Final Answer:
@propertyWrapper struct Capitalized { var wrappedValue: String } -> Option A
Quick Check:
Property wrapper syntax = @propertyWrapper before struct [OK]
Hint: Put @propertyWrapper before struct/class, not before property [OK]
Common Mistakes:
Placing @propertyWrapper before the property instead of the struct
Omitting the @propertyWrapper attribute
Trying to declare property wrapper as a variable
3. Given the code below, what will be printed?
@propertyWrapper
struct Trimmed {
var wrappedValue: String
init(wrappedValue: String) {
self.wrappedValue = wrappedValue.trimmingCharacters(in: .whitespaces)
}
}
struct User {
@Trimmed var name: String
}
let user = User(name: " Alice ")
print(user.name)
medium
A. "Alice"
B. " Alice "
C. Compilation error
D. "Alice "
Solution
Step 1: Understand the property wrapper behavior
The Trimmed wrapper trims whitespace from the string when initialized in its init. So the initial value " Alice " is trimmed to "Alice".
Step 2: Check the printed value
The user.name accesses the wrapped value, which is trimmed. So printing user.name outputs "Alice" without spaces.
Final Answer:
"Alice" -> Option A
Quick Check:
Trimmed wrapper removes spaces = "Alice" [OK]
Hint: Property wrapper trims on init, so output is trimmed [OK]
Common Mistakes:
Assuming original spaces remain
Thinking didSet runs before init
Overlooking the trimming in init
4. Identify the error in the following property wrapper declaration:
@propertyWrapper
struct Positive {
var wrappedValue: Int
init(wrappedValue: Int) {
if wrappedValue < 0 {
wrappedValue = 0
}
self.wrappedValue = wrappedValue
}
}
medium
A. No error, code is correct
B. Missing @propertyWrapper attribute
C. wrappedValue property must be a computed property
D. Cannot assign to parameter 'wrappedValue' inside init
Solution
Step 1: Analyze the init parameter usage
In Swift, function parameters are constants and cannot be assigned new values. The line wrappedValue = 0 inside the init tries to assign to the parameter, which causes an error.
Step 2: Check other options
The @propertyWrapper attribute is present, so B is wrong. The wrappedValue can be stored or computed, so C is wrong. The code has an error, so A is wrong.
Final Answer:
Cannot assign to parameter 'wrappedValue' inside init -> Option D
Quick Check:
Function parameters are constants = assignment error [OK]
Hint: Don't assign to init parameters; use a local var instead [OK]
Common Mistakes:
Trying to assign directly to init parameters
Thinking wrappedValue must be computed
Ignoring the @propertyWrapper attribute
5. You want to create a property wrapper Clamped that limits an Int value between a minimum and maximum. Which of the following is the correct way to declare it so that you can use it like @Clamped(min: 0, max: 10) var score: Int?
hard
A. @propertyWrapper struct Clamped {
var wrappedValue: Int
init(min: Int, max: Int) {
wrappedValue = 0
}
}
B. @propertyWrapper struct Clamped {
private var value: Int
let min: Int
let max: Int
var wrappedValue: Int {
get { value }
set { value = min(max(newValue, min), max) }
}
init(wrappedValue: Int, min: Int, max: Int) {
self.min = min
self.max = max
self.value = min(max(wrappedValue, min), max)
}
}
C. @propertyWrapper struct Clamped {
var wrappedValue: Int
init(wrappedValue: Int) {
wrappedValue = 0
}
}
D. @propertyWrapper struct Clamped {
var wrappedValue: Int {
didSet {
if wrappedValue < min { wrappedValue = min }
if wrappedValue > max { wrappedValue = max }
}
}
let min: Int
let max: Int
}
Solution
Step 1: Understand the requirements for Clamped
The wrapper must accept min and max parameters, clamp the wrappedValue between them, and allow usage with @Clamped(min: 0, max: 10).
Step 2: Analyze each option
@propertyWrapper struct Clamped {
private var value: Int
let min: Int
let max: Int
var wrappedValue: Int {
get { value }
set { value = min(max(newValue, min), max) }
}
init(wrappedValue: Int, min: Int, max: Int) {
self.min = min
self.max = max
self.value = min(max(wrappedValue, min), max)
}
} correctly defines min and max as let constants, stores the value privately, clamps in init and setter, and has the correct init signature. @propertyWrapper struct Clamped {
var wrappedValue: Int
init(min: Int, max: Int) {
wrappedValue = 0
}
} lacks wrappedValue initialization and clamping logic. @propertyWrapper struct Clamped {
var wrappedValue: Int
init(wrappedValue: Int) {
wrappedValue = 0
}
} does not accept min and max parameters. @propertyWrapper struct Clamped {
var wrappedValue: Int {
didSet {
if wrappedValue < min { wrappedValue = min }
if wrappedValue > max { wrappedValue = max }
}
}
let min: Int
let max: Int
} tries to clamp in didSet but does not initialize wrappedValue properly and does not clamp in init, which can cause invalid initial values.
Final Answer:
@propertyWrapper struct Clamped {
private var value: Int
let min: Int
let max: Int
var wrappedValue: Int {
get { value }
set { value = min(max(newValue, min), max) }
}
init(wrappedValue: Int, min: Int, max: Int) {
self.min = min
self.max = max
self.value = min(max(wrappedValue, min), max)
}
} -> Option B
Quick Check:
Clamped wrapper needs init with min/max and clamping in setter [OK]
Hint: Use init with wrappedValue and params; clamp in setter and init [OK]
Common Mistakes:
Not accepting min and max in init
Not clamping value on initialization
Trying to clamp only in didSet without proper init
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.