Difficulty: Beginner | Easy | Normal | Challenging
This article has been developed using Xcode 11.4.1, and Swift 5.2.2
- You will be expected to be aware how to make a Single View Application in Swift or a hello, world equivalent
- It would be helpful to understand something about lazy variables would be useful
- Property Wrappers rely on Generics in Swift
lazy variables: A technique in that a property is only created when it is needed Property Wrappers: A property wrapper adds a layer of separation between code that manages how a property is stored and the code that defines a property
Using Lazy in Swift is useful as it defers initialization of a value until its first access. This is equivalent functionality to wrapping a value in a computed get - lazy makes your code more elegant, easy to read and of course maintainable.
Here is an example of the lazy instantiation of a struct (if you follow along with the Playground, make sure you comment out one of the People
instances at a time or the compiler will tell you that you have an invalid declaration of 'People
')
Effectively for each property on the struct
you'd need to have one of these sets of getters and setters. What if you could use a repeatable peice of code that would allow you to be able to reuse code.
The idea here is that we can reuse the Wrapper
for as many properties as we would like on the People
struct
. This gives the following code:
Effectively we are abstracting the @propertyWrapper
away from our struct
or class
instances. The Wrapper
provides transparency since when we are using the Wrapper
using generics we are simply using an Array
of String
.
It is really common to use ISO8601DateFormatter
to provide a standardized way of presenting Data and Time. Since this can be reused in many struct
and class
instances, this is certainly is great use of Swift's Property Wrappers.
Where of course in the user.createdAt
is the date, and print(user.createdAt)
are in fact the same date, but the second is formatted for the screen.
We can go as far as to look at our two createdAt properties on our user instance: user.createdAt
and user.$createdAt
Each of the two examples above gives us two different outputs - since the second of the two is a projectedValue.
So the $ indicates that we want to access the property wrapper itself rather than the property that it is wrapping.
type(of: user.createdAt) // Foundation.Date.Type type(of: user.$createdAt) // String.Type
Now of course to use projectedValue we need to have a var projectedValue property in our propertyWrapper - which is of course true in our example code as set out (which represents a user).
This means that user.createdAt
is a simple date, but user.$createdAt
is a nicely formatted date in this example.
Awesome!
Property wrappers are a Swift feature that can help you write easy to read and maintainable code in Swift. They have been available since Swift 5.1, and have particular power when coupled with SwiftUI - so this is certainly something you should look at as you enhance your understanding of Swift and iOS/iPadOS.
When creating code you should always think about reusability, what a great use of abstraction in the constructs of the language!
The code from this is included in the attached Repo.
If you've any questions, comments or suggestions please hit me up on Twitter