Bird
Raised Fist0
Swiftprogramming~20 mins

@propertyWrapper declaration in Swift - Practice Problems & Coding Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
Swift Property Wrapper Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ Predict Output
intermediate
2:00remaining
What is the output of this Swift code using @propertyWrapper?
Consider the following Swift code that uses a property wrapper. What will be printed when running this code?
Swift
import Foundation

@propertyWrapper
struct Capitalized {
    private var value: String = ""
    var wrappedValue: String {
        get { value }
        set { value = newValue.capitalized }
    }
}

struct Person {
    @Capitalized var name: String
}

var p = Person()
p.name = "john doe"
print(p.name)
A"John Doe"
B"john Doe"
C"john doe"
D"JOHN DOE"
Attempts:
2 left
💡 Hint
Look at how the setter modifies the string using the capitalized property.
❓ Predict Output
intermediate
2:00remaining
What error does this Swift @propertyWrapper code produce?
Examine this Swift code using @propertyWrapper. What error will it produce when compiled?
Swift
@propertyWrapper
struct NumberWrapper {
    var wrappedValue: Int

    init() {
        wrappedValue = 0
    }
}

struct Data {
    @NumberWrapper var number: Int
}

let d = Data()
AError: Cannot assign to property: 'wrappedValue' is a get-only property
BError: Property wrapper must have an initial value
CNo error, compiles successfully
DError: Missing argument for parameter 'wrappedValue' in call
Attempts:
2 left
💡 Hint
Check how the property wrapper is initialized and what initializers are available.
🔧 Debug
advanced
2:00remaining
Why does this @propertyWrapper code cause a runtime crash?
This Swift code compiles but crashes at runtime. What is the cause of the crash?
Swift
@propertyWrapper
struct Positive {
    private var value: Int
    var wrappedValue: Int {
        get { value }
        set {
            guard newValue > 0 else {
                fatalError("Value must be positive")
            }
            value = newValue
        }
    }

    init(wrappedValue: Int) {
        self.wrappedValue = wrappedValue
    }
}

struct Account {
    @Positive var balance: Int
}

let a = Account(balance: -10)
AThe code crashes because value is not initialized before use
BThe fatalError is triggered because the initial wrappedValue is negative
CThe code crashes due to infinite recursion in the setter
DNo crash occurs; the code runs fine
Attempts:
2 left
💡 Hint
Look at how the initial wrappedValue is assigned and how the setter guard works.
📝 Syntax
advanced
2:00remaining
Which option correctly declares a @propertyWrapper with projectedValue?
Choose the correct Swift code that declares a @propertyWrapper with a projectedValue property.
A
@propertyWrapper
struct Wrapper {
    var wrappedValue: Int
    var projectedValue: String {
        "Value is \(wrappedValue)"
    }
}
B
@propertyWrapper
struct Wrapper {
    var wrappedValue: Int
    var projectedValue: Int {
        wrappedValue * 2
    }
}
C
@propertyWrapper
struct Wrapper {
    var wrappedValue: Int
    var projectedValue: Int {
        get { wrappedValue * 2 }
    }
}
D
@propertyWrapper
struct Wrapper {
    var wrappedValue: Int
    var projectedValue: Int {
        set { wrappedValue = newValue }
    }
}
Attempts:
2 left
💡 Hint
The projectedValue must be a readable property, usually with a getter.
🚀 Application
expert
2:00remaining
How many items are in the resulting array after using this @propertyWrapper in a loop?
Given this Swift code using a @propertyWrapper that tracks assignments, how many elements will be in the assignments array after the loop?
Swift
@propertyWrapper
class Tracker {
    private(set) var assignments: [Int] = []
    var wrappedValue: Int {
        didSet {
            assignments.append(wrappedValue)
        }
    }
    init(wrappedValue: Int) {
        self.wrappedValue = wrappedValue
    }
}

struct Data {
    @Tracker var value: Int
}

var data = Data(value: 0)
for i in 1...3 {
    data.value = i
}

let count = data.$value.assignments.count
print(count)
A4
B3
C1
D0
Attempts:
2 left
💡 Hint
Remember the initial assignment in init and the didSet calls in the loop.

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

  1. 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.
  2. 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.
  3. Final Answer:

    To add reusable behavior to variables by controlling their access and storage -> Option C
  4. Quick Check:

    @propertyWrapper purpose = reusable variable behavior [OK]
Hint: Remember: @propertyWrapper controls variable behavior [OK]
Common Mistakes:
  • 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

  1. 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.
  2. 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.
  3. Final Answer:

    @propertyWrapper struct Capitalized { var wrappedValue: String } -> Option A
  4. 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

  1. 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".
  2. Step 2: Check the printed value

    The user.name accesses the wrapped value, which is trimmed. So printing user.name outputs "Alice" without spaces.
  3. Final Answer:

    "Alice" -> Option A
  4. 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

  1. 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.
  2. 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.
  3. Final Answer:

    Cannot assign to parameter 'wrappedValue' inside init -> Option D
  4. 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

  1. 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).
  2. 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.
  3. 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
  4. 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 unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard