Bird
Raised Fist0
Swiftprogramming~10 mins

Custom validation property wrappers in Swift - Interactive Code Practice

Choose your learning style10 modes available
Practice - 5 Tasks
Answer the questions below
1fill in blank
easy

Complete the code to declare a property wrapper named ValidateNonEmpty that checks if a string is not empty.

Swift
import Foundation

@propertyWrapper
struct ValidateNonEmpty {
    private var value: String = ""

    var wrappedValue: String {
        get { value }
        set {
            if newValue.isEmpty {
                value = "[1]"
            } else {
                value = newValue
            }
        }
    }

    init(wrappedValue: String) {
        self.wrappedValue = wrappedValue
    }
}
Drag options to blanks, or click blank then click option'
A"invalid"
B"empty"
C"default"
D"none"
Attempts:
3 left
💡 Hint
Common Mistakes
Leaving the value empty instead of assigning a default invalid string.
Not handling the empty string case in the setter.
2fill in blank
medium

Complete the code to add a validation check that the wrapped string has at least 5 characters.

Swift
import Foundation

@propertyWrapper
struct ValidateLength {
    private var value: String = ""

    var wrappedValue: String {
        get { value }
        set {
            if newValue.count < [1] {
                value = "Too short"
            } else {
                value = newValue
            }
        }
    }

    init(wrappedValue: String) {
        self.wrappedValue = wrappedValue
    }
}
Drag options to blanks, or click blank then click option'
A3
B10
C5
D1
Attempts:
3 left
💡 Hint
Common Mistakes
Using a number smaller or larger than 5, which breaks the intended validation.
Confusing the comparison operator.
3fill in blank
hard

Fix the error in the property wrapper to correctly validate that the wrapped value is always uppercase.

Swift
import Foundation

@propertyWrapper
struct ValidateUppercase {
    private var value: String = ""

    var wrappedValue: String {
        get { value }
        set {
            if newValue == newValue.[1]() {
                value = newValue
            } else {
                value = newValue.uppercased()
            }
        }
    }

    init(wrappedValue: String) {
        self.wrappedValue = wrappedValue
    }
}
Drag options to blanks, or click blank then click option'
Alowercased
Bcapitalized
CtrimmingCharacters
Duppercased
Attempts:
3 left
💡 Hint
Common Mistakes
Using lowercased() which checks for lowercase instead.
Using capitalized() which capitalizes only the first letter.
4fill in blank
hard

Fill both blanks to create a property wrapper that validates an integer is within a range 1 to 100.

Swift
import Foundation

@propertyWrapper
struct ValidateRange {
    private var value: Int = 1

    var wrappedValue: Int {
        get { value }
        set {
            if newValue [1] 1 && newValue [2] 100 {
                value = newValue
            } else {
                value = 1
            }
        }
    }

    init(wrappedValue: Int) {
        self.wrappedValue = wrappedValue
    }
}
Drag options to blanks, or click blank then click option'
A>=
B<=
C>
D<
Attempts:
3 left
💡 Hint
Common Mistakes
Using > or < which exclude boundary values.
Reversing the operators.
5fill in blank
hard

Fill all three blanks to create a property wrapper that validates a string contains only letters and is capitalized.

Swift
import Foundation

@propertyWrapper
struct ValidateLettersCapitalized {
    private var value: String = ""

    var wrappedValue: String {
        get { value }
        set {
            let letters = CharacterSet.[1]
            if newValue.rangeOfCharacter(from: letters.inverted) == nil && newValue == newValue.[2]() {
                value = newValue
            } else {
                value = newValue.[3]()
            }
        }
    }

    init(wrappedValue: String) {
        self.wrappedValue = wrappedValue
    }
}
Drag options to blanks, or click blank then click option'
Aletters
Bcapitalized
Dlowercased
Attempts:
3 left
💡 Hint
Common Mistakes
Using wrong CharacterSet like alphanumerics.
Confusing capitalized() with uppercased().
Setting value to capitalized() instead of lowercased() on invalid input.

Practice

(1/5)
1. What is the main purpose of a custom validation property wrapper in Swift?
easy
A. To automatically check and enforce rules on property values
B. To change the type of a property at runtime
C. To make properties private and inaccessible
D. To store multiple values in a single property

Solution

  1. Step 1: Understand property wrappers

    Property wrappers in Swift add extra behavior to properties, such as validation.
  2. Step 2: Identify validation role

    Custom validation wrappers check if values meet certain rules before storing them.
  3. Final Answer:

    To automatically check and enforce rules on property values -> Option A
  4. Quick Check:

    Validation = enforce rules [OK]
Hint: Validation wrappers enforce rules on data automatically [OK]
Common Mistakes:
  • Thinking wrappers change property type
  • Confusing validation with access control
  • Assuming wrappers store multiple values
2. Which of the following is the correct syntax to declare a custom validation property wrapper named NonEmpty for a String property in Swift?
easy
A. var name: @NonEmpty String
B. var @NonEmpty name: String
C. @NonEmpty var name: String
D. NonEmpty var name: String

Solution

  1. Step 1: Recall property wrapper syntax

    In Swift, property wrappers are applied with @ before the wrapper name, placed before the variable declaration.
  2. Step 2: Match correct syntax

    Correct syntax is @WrapperName var propertyName: Type, so @NonEmpty var name: String is correct.
  3. Final Answer:

    @NonEmpty var name: String -> Option C
  4. Quick Check:

    @WrapperName before var = correct syntax [OK]
Hint: Use @ before wrapper name, then var property [OK]
Common Mistakes:
  • Placing @ after var
  • Putting wrapper inside type
  • Omitting @ symbol
3. Consider this Swift code using a custom validation property wrapper Positive that only allows positive integers:
 @propertyWrapper
 struct Positive {
     private var value: Int = 1
     var wrappedValue: Int {
         get { value }
         set { value = newValue > 0 ? newValue : 1 }
     }
 }

 struct Account {
     @Positive var balance: Int
 }

 let acc = Account()
 print(acc.balance)
What will be printed when this code runs?
medium
A. 1
B. 0
C. nil
D. Compilation error

Solution

  1. Step 1: Understand default value in wrapper

    The wrapper's private value starts at 1, and sets new values only if positive; else resets to 1.
  2. Step 2: Check initial property value

    Account's balance uses @Positive but no initial value is set, so it uses wrapper's default 1.
  3. Final Answer:

    1 -> Option A
  4. Quick Check:

    Default wrapper value = 1 [OK]
Hint: Default wrapper value used if no initial value given [OK]
Common Mistakes:
  • Expecting 0 as default
  • Assuming nil is possible
  • Thinking code won't compile
4. This Swift code attempts to create a custom validation property wrapper NonNegative but has an error:
 @propertyWrapper
 struct NonNegative {
     var value: Int
     var wrappedValue: Int {
         get { value }
         set { if newValue >= 0 { value = newValue } }
     }
 }

 struct Score {
     @NonNegative var points: Int = -5
 }
What is the main problem causing this code to fail?
medium
A. wrappedValue setter does not handle negative values correctly
B. Property wrapper lacks an initializer to set initial value
C. Cannot assign default value to property with wrapper
D. Missing @ symbol before property wrapper

Solution

  1. Step 1: Check property wrapper requirements

    Property wrappers must have an init(wrappedValue:) to accept initial values.
  2. Step 2: Identify missing initializer

    NonNegative lacks init(wrappedValue:) so compiler cannot assign -5 to points.
  3. Final Answer:

    Property wrapper lacks an initializer to set initial value -> Option B
  4. Quick Check:

    Missing init(wrappedValue:) = error [OK]
Hint: Add init(wrappedValue:) to accept initial values [OK]
Common Mistakes:
  • Ignoring missing initializer
  • Blaming setter logic
  • Thinking default value assignment is invalid
5. You want to create a custom validation property wrapper LimitedLength that limits a String property's length to a maximum number of characters. Which of the following implementations correctly enforces this limit and allows setting the max length when declaring the property?
 @propertyWrapper
 struct LimitedLength {
     private var value: String = ""
     private let maxLength: Int

     var wrappedValue: String {
         get { value }
         set {
             if newValue.count <= maxLength {
                 value = newValue
             } else {
                 value = String(newValue.prefix(maxLength))
             }
         }
     }

     // Which initializer is correct?
     ???
 }

 struct User {
     @LimitedLength(maxLength: 5) var username: String
 }
hard
A. init(maxLength: Int) { self.maxLength = maxLength }
B. init(wrappedValue: String) { self.value = wrappedValue; maxLength = 5 }
C. init() { maxLength = 5 }
D. init(wrappedValue: String, maxLength: Int) { self.maxLength = maxLength; self.value = wrappedValue }

Solution

  1. Step 1: Understand property wrapper initialization with parameters

    When a wrapper has parameters and initial value, it needs init(wrappedValue:maxLength:) to accept both.
  2. Step 2: Match initializer to usage

    Usage passes maxLength: 5 and no initial value, so init(wrappedValue:maxLength:) fits best to set both.
  3. Final Answer:

    init(wrappedValue: String, maxLength: Int) { self.maxLength = maxLength; self.value = wrappedValue } -> Option D
  4. Quick Check:

    Use init(wrappedValue:maxLength:) for parameters [OK]
Hint: Use init(wrappedValue:maxLength:) to accept value and limit [OK]
Common Mistakes:
  • Using init(maxLength:) only misses initial value
  • Using init() without parameters
  • Using init(wrappedValue:) without maxLength
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