All the things you can do using Properties in Swift

Set the property as read only

var readOnlyProperty : String {
		get {
			return "this is a read only property"
		}
	}

Add a setter to the property. Make a note of newValue. This is a predefined swift variable which holds the new value you just passed in.

private var oldSetterAndGetter = "oldSetterAndGetter"
var setterAndGetter : String {
	get {
		return oldSetterAndGetter
	}
	set {
		oldSetterAndGetter = oldSetterAndGetter + " " + newValue
	}
}
var test = TestProperties()
// will return an error saying, this is a read-only property
// test.readOnlyProperty = "readonly"
test.setterAndGetter = "redflowerinc"
// this will return a combination of your new value and the old value
print(test.setterAndGetter)

DidSet and WillSet. This is self explanatory

var setterAndGetter : String = "" {
	didSet {
		print("didSet "+oldValue)
	}
	willSet {
		print("willSet "+newValue)
	}
}

Make a note of the keywords oldValue and newValue. These are predefined values in Swift to hold the old and new property values. Take a look at the output below. The first time, the value of the property setterAndGetter is empty. The second time you call this property, it prints the older value.

var test = TestProperties()
test.setterAndGetter = "redflowerinc"
test.setterAndGetter = "redflowerinc_newValue"
print(test.setterAndGetter)
// didSet 
// willSet redflowerinc_newValue
// didSet redflowerinc
// redflowerinc_newValue

Next we move on to PropertyWrapper. A property wrapper adds a layer of separation between code that manages how a property is stored and the code that defines a property. In layman’s terms, it’s basically a helper method which will add checks for you, every time you access a property.

Use this if you only need it or you are planning to use property wrappers. Not worth the effort, if you don’t repeat the piece of code again and again. In the example below, I have shown the snippet of code using property wrappers and just using properties.

// without property wrapper
private var temporaryNumber = 0
var twelveOrLess : Int {
	get {
		temporaryNumber
	}
	set {
		temporaryNumber = min(newValue, 12)
	}
}

// with property wrapper	
@propertyWrapper
struct TwelveOrLess {
	private var number = 0
	var wrappedValue: Int {
		get { return number }
		set { number = min(newValue, 12) }
	}
}

Another example showing a string comparison. Note the keyword wrappedValue

@propertyWrapper
struct StringContainsMyName {
	private var websiteName = "redflowerinc"
	var wrappedValue : String {
		set {
		     if(newValue.caseInsensitiveCompare(websiteName) == .orderedSame) {
				websiteName = newValue
			} else {
				websiteName = "does not contain website name"
			}
		}
		get {
			return websiteName
		}
	}
}
@StringContainsMyName var websiteName : String

// Usage is shown below
var test = TestProperties()
test.websiteName = "redflowerinc1"
print(test.websiteName)

Minor one, but you can also initialize the wrapped value as shown below.

init(wrappedValue: Int) {
        maximum = 12
        number = min(wrappedValue, maximum)
    }
    init(wrappedValue: Int, maximum: Int) {
        self.maximum = maximum
        number = min(wrappedValue, maximum)
    }

Moving on, lets look into projectedValue e.g. let’s consider you are trying to download a huge file, and store it in a disk. You give it a try and it fails, then the property basically adjusts the value and stores the default. Please refer the example below. I am trying to save the name as redflowerinc If it doesn’t match, then it sets an error message saying does not contain website name
That’s it.

@propertyWrapper
struct StringContainsMyName {
	private var myName = "redflowerinc"
	var projectedValue = false
	var wrappedValue : String {
		set {
			if(newValue.caseInsensitiveCompare(myName) == .orderedSame) {
				myName = newValue
				projectedValue = true
			} else {
				myName = "does not contain website name"
				projectedValue = false
			}
		}
		get {
			return myName
		}
	}
	init(wrappedValue: String) {
		myName = "redflowerinc"
	}
	init() {
		myName = "redflower init"
	}
}

struct TestProjectedValue {
	@StringContainsMyName var testName : String = "sir"
	mutating func changeProperty(yourname name: String) -> Bool {
		testName = name
		return $testName
	}
}

var test = TestProjectedValue()
test.testName = "sir"
print("stored value",test.testName," ",test.$testName)

Leave a Reply

Your email address will not be published. Required fields are marked *