An Introduction to Swift Property Wrappers
Learn what Swift property wrappers are, and explore how they provide a useful way to make computed properties reusable across different classes.
Now that the topics of Swift classes and structures have been covered, this chapter will introduce a related topic in the form of property wrappers. Introduced in Swift 5.1, property wrappers provide a way to reduce the amount of duplicated code involved in writing getters, setters, and computed properties in class and structure implementations.
Understanding property wrappers
When values are assigned or accessed via a property within a class or structure instance, it is sometimes necessary to perform some form of transformation or validation on that value before it is stored or read. As outlined in the earlier “Swift Object-Oriented Programming” lessons, this type of behavior can be implemented through the creation of computed properties. Frequently, patterns emerge where a computed property is common to multiple classes or structures. Prior to the introduction of Swift 5.1, the only way to share the logic of a computed property was to duplicate the code and embed it into each class or structure implementation. Not only is this inefficient but a change in the behavior of the computation must be manually propagated across all the entities that use it.
To address this shortcoming, Swift 5.1 introduced a feature known as property wrappers. Property wrappers essentially allow the capabilities of computed properties to be separated from individual classes and structures and reused throughout the app codebase.
A simple property wrapper example
Perhaps the best way to understand property wrappers is to study a very simple example. Imagine a structure with a String
property intended to contain a city name. Such a structure might read as follows:
struct Address {
var city: String
}
If the class was required to store the city name in uppercase, regardless of how it was entered by the user, a computed property such as the following might be added to the structure:
struct Address {
private var cityname: String = ""
var city: String {
...