Introduction to Property Wrappers

Property wrappers are a powerful feature introduced in Swift 5.1 that allow you to define reusable logic for getting and setting property values. They help you reduce boilerplate and enforce consistent behavior across your codebase.

Basic Example

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

struct User {
    @Capitalized var name: String
}

var user = User(name: "john")
print(user.name) // Output: John

Why Use Property Wrappers?

  • Encapsulate repetitive logic
  • Improve code readability
  • Promote reusability
  • Enforce constraints and validation

Advanced Usage

@propertyWrapper
struct Clamped {
    var value: Value
    let range: ClosedRange
    var wrappedValue: Value {
        get { value }
        set { value = min(max(newValue, range.lowerBound), range.upperBound) }
    }
    init(wrappedValue: Value, _ range: ClosedRange) {
        self.range = range
        self.value = min(max(wrappedValue, range.lowerBound), range.upperBound)
    }
}

struct Percentage {
    @Clamped(0...100) var value: Int = 0
}

var percent = Percentage()
percent.value = 150
print(percent.value) // Output: 100

Best Practices

  1. Use property wrappers for cross-cutting concerns (validation, formatting, caching, etc.)
  2. Document your wrappers for clarity
  3. Be mindful of performance and side effects

Conclusion

Property wrappers are a great way to write cleaner, more maintainable Swift code. By encapsulating logic and promoting reusability, they help you build robust iOS applications.