Property wrappers in swift Part-2

Swifty
2 min readDec 23, 2019

From Part 1, We got to have an idea on Property wrappers, how does it works.

Let’s use the same struct we used in Part 1,

@propertyWrapper
struct PostiveNumber {
private var number: Int = 0
var wrappedValue: Int {
get {
return number
}
set(newInt) {
if newInt < 0 {
number = newInt * -1
} else {
number = newInt
}
}
}
}
//Using the Property Wrapper
class Rectangle {
@PostiveNumber private var width: Int
@PostiveNumber private var height: Int
func area() -> Int {
width = -10
height = 15
print("Width \(width)")//prints 10
return width * height
}
}

Now If we try to initialize width or height to any value, then an error will be thrown. To Achieve this, property wrappers should have initializers as follows

PostiveNumber definition includes two initializers — init() and init(wrappedValue: Int)

@propertyWrapper
struct PostiveNumber {
private var number: Int
var wrappedValue: Int {
get {
return number
}
set(newInt) {
if newInt < 0 {
number = newInt * -1
} else {
number = newInt
}
}
}

init() {
number = 0
} init(wrappedValue: Int) {
if wrappedValue > 0 {
number = wrappedValue
} else {
number = wrappedValue * -1
}
}
}

Now, PositiveNumber instance that wraps the properties width and height are created with above specified init methods.

when initial values for width and height are not given just like below, it is created with init()

     @PostiveNumber private var width: Int
@PostiveNumber private var height: Int

Addition to this, Having those init methods also let us provide initial values to properties as follow. In this case PostiveNumber is created with init(wrappedValue: Int)

     @PostiveNumber private var width: Int = -10
@PostiveNumber private var height: Int = 30

print(width)//Prints 10

Adding Functionalities to Property Wrappers

In addition to these, property wrappers will be able to expose additional functionalities with a property called projectedValue. It can be of any type and it helps us with additional things to be done with a property.

@propertyWrapper
struct PostiveNumber {
private var number: Int

var projectedValue = 0 //Saves previous value in this case. it can be any type not just limited to Int
var wrappedValue: Int {
get {
return number
}
set(newInt) {
projectedValue = number
if newInt < 0 {
number = newInt * -1
} else {
number = newInt
}
}
}

init() {
number = 0
} init(wrappedValue: Int) {
if wrappedValue > 0 {
number = wrappedValue
} else {
number = wrappedValue * -1
}
}
}

In our case, we defined projectedValue to be of type Int and it saves the previous value of number before setting the new value.

To access the projectedValue of the wrapper, we prefix property name with $ symbol. This is brilliant as it is simple and swift doesn’t allow us to create a var name with $ prefix So, We are free to use this.

width = -10
print(width)//prints 10
width = 20
print(width) //prints 20
print($width) //prints 10

Thats all folks, Merry Christmas and Happy New Year!

--

--