Hello boys and girls, Leo here. I’m very excited to inform you all that today we will talk about how to project a value from a property wrapper.
Today we will explore one great feature of property wrappers, the projected value. It is very useful when you want to have a little more info about the wrapped value. For example you have a property wrapper that set a max limit to the int, you can project a boolean value that says if the property was set with more than the max value or less.
Let’s code!
Problem
You need more information on wrapped values and don’t want to split the logic outside the property context. Ex: You receive a text but the only important info is the first 3 characters and it must be uppercase to show to the user. Also, you want to know if it comes bigger than 3 characters from the backend or not.
First we need to write our property wrapper:
@propertyWrapper struct UpperCaseMask { private var text: String //1 var projectedValue: Bool //2 init() { self.text = "" self.projectedValue = false } var wrappedValue: String { //3 get {return text} set { if newValue.count > 3 { text = newValue.prefix(3).uppercased() projectedValue = false } else { text = newValue.uppercased() projectedValue = true } } } }
On 1 comment mark, you see what type will be your wrapper, in this case, will be a string. The 2 comment mark explores the concept that we are talking about here, you can have another value at the moment you set a new/create value from the property, which in this case, will be a boolean.
The 3 comment mark shows a standard wrappedValue implementation, but as you can see depending on what we set to the property you can specify a projected value. This is useful because you don’t need to recalculate that IF statement anywhere else, this way you put some logic on the property itself.
Now you can annotate a property with that and voilá:
struct Home { @UpperCaseMask public var homeCode: String init(homeCode: String) { self.homeCode = homeCode } } var home1 = Home(homeCode: "brln123123") print(home1.$homeCode, home1.homeCode) // 1 home1.homeCode = "can" print(home1.$homeCode, home1.homeCode) // 1
If you copy and paste it into your playgrounds you will see this:
You can notice that in the first case we cut the rest of the useless info and transformed it into some “masked” string, and in the second case we only upperCase it. To get the projected value we need to put a $ mark before the property name.
Using the Projected Value From a Property Wrapper
The last thing about this feature is, that if you access the projected value inside the struct Home, you only use the $ mark and the job is done.
struct Home { @UpperCaseMask public var homeCode: String init(homeCode: String) { self.homeCode = homeCode } func getHomeCodeFullDescription() -> String { if $homeCode { // < - - - Here return "We just need to uppercase it" } else { return "We need to cut and uppercase it" } } }
And if you test it you get:
var home1 = Home(homeCode: "brln123123") print(home1.$homeCode, home1.homeCode, home1.getHomeCodeFullDescription()) home1.homeCode = "can" print(home1.$homeCode, home1.homeCode, home1.getHomeCodeFullDescription())
Resulting in the console below:
And we are done!
Summary – Project a Value From a Property Wrapper
In expansion to the wrapped value, a property wrapper can show extra usefulness by using a projected value—for illustration, a property wrapper that manages get to to a database can uncover a function on its projected value.
That’s all my people, I hope you liked reading this article as much as I enjoyed writing it. If you want to support this blog you can Buy Me a Coffee or leave a comment saying hello. You can also sponsor posts and I’m open to freelance writing!
You can reach me on LinkedIn or Twitter and send me an e-mail through the contact page.
Thanks for the reading and… That’s all folks.
Credits – image