Getters and Setters in Swift
Learn how to implement getters and setters for Swift properties, and learn about Swift 5.5 support for getters that can throw an error.
A getter in Swift allows access to a property, and a setter allows a property to be set. This post presents an overview of getters and setters, and examples of some Swift features related to getters and setters:
- Automatically Generated Getters and Setters
- get Getter
a. get throws (new in Swift 5.5) - set Setter
- willSet
- didSet
a. ‘didSet’ cannot be provided together with a getter
b. ‘willSet’ cannot be provided together with a getter
c. ‘didSet’ cannot be provided together with a setter
d. ‘willSet’ cannot be provided together with a setter
Automatically Generated Getters and Setters
When an instance property is defined in Swift using var, a getter and setter is automatically generated:
class Notes {
var canSave = false
}
notes = Notes()
notes.canSave // Getter is available
notes.canSave = true // Setter is available
When an instance property is defined in Swift using let, only a getter is available:
class Store {
let canOrder = false
}
store = Store()
store.canOrder // Getter is available
// This will not compile and cause the error:
// "Cannot assign to property 'canSave'
// is a 'let' constant"
store.canOrder = true
get Getter
One way to implement a variable property without an exposed setter is to indicate a variable as private(set):
class Store {
private(set) var canOrder = false
}
// Create a store instance
store = Store()
store.canOrder // Getter is available
// This will not compile and cause the error:
// "Cannot assign to property: 'canOrder'
// setter is inaccessible"
store.canOrder = true
Another way to implement a variable property without an exposed setter is to use get. Often get is used to expose a getter to a private property:
class Store {
private var _canOrder = false
var canOrder: Bool {
get { return _canOrder }
}
}
// Create a store instance
store = Store()
store.canOrder // Getter is available
// This will not compile and cause the error:
// "Cannot assign to property: 'canOrder'
// is a get-only property"
store.canOrder = true
get throws (new in Swift 5.5)
Starting in Swift 5.5, throws is available for getters defined with get:
class Notes {
func isDatabaseAvailable() throws -> Bool {
/* ... */
}
var canSave: Bool {
get throws {
return try isDatabaseAvailable()
}
}
}
notes = Notes()
do {
if try notes.canSave {
// Handle logic
}
}
catch {
// Handle error
}
set Setter
The set keyword can be used to implement an explicit setter in Swift. Often set is used to expose a setter for a private property and apply additional logic:
class Notes {
func isDatabaseAvailable() -> Bool {
/* ... */
}
private var _canSave = false
var canSave: Bool {
get { return _canSave }
set {
if isDatabaseAvailable() {
_canSave = newValue
}
}
}
}
willSet
If explicit getters and setters using get and set are not defined, willSet can be used to take action before a new value is set for a property:
class Notes {
func storePreviousSaveValue(_ canSave: Bool) {}
var canSave = false {
willSet {
// Inside of willSet, the property
// canSave will be the old value,
// before a new one is set
storePreviousSaveValue(canSave)
}
}
}
// Creates an instance of notes with
// notes.canSave initialized to false
notes = Notes()
// willSet will be called while notes.canSave is
// false, so storePreviousSaveValue is called
// with false, then notes.canSave is set to true
notes.canSave = true
didSet
If explicit getters and setters using get and set are not defined, didSet can be used to take action after a new value is set for a property:
class Notes {
@IBOutlet var saveButton: UIButton?
var canSave = false {
didSet {
// Inside of didSet, the property
// canSave will have the new value
saveButton?.userInteractionEnabled = canSave
}
}
}
// Creates an instance of notes with
// notes.canSave initialized to false
notes = Notes()
// didSet will be called after notes.canSave is
// set to true, so saveButton?.userInteractionEnabled
// will be set to true
notes.canSave = true
'didSet' cannot be provided together with a getter
If only didSet and get are implemented, didSet will never be called because a get-only property cannot be set:
var canSave: Bool {
// This causes the compiler error:
// "‘didSet’ cannot be provided
// together with a getter"
get { /* ... */ }
didSet { /* ... */ }
}
'willSet' cannot be provided together with a getter
If only willSet and get are implemented, willSet will never be called because a get-only property cannot be set:
var canSave: Bool {
// This causes a compiler error:
// "'willSet' cannot be provided
// together with a getter"
get { /* ... */ }
willSet { /* ... */ }
}
'didSet' cannot be provided together with a setter
If only didSet and set are implemented, didSet should instead be implemented inside of the set setter:
var canSave: Bool {
// This causes a compiler error:
// "'didSet' cannot be provided
// together with a setter"
set { /* ... */ }
didSet { /* ... */ }
}
// This is a better alternative:
var canSave: Bool {
set {
canSave = newValue
// Add code for didSet here,
// after a new value is set
}
}
'willSet' cannot be provided together with a setter
If only willSet and set are implemented, willSet should instead be implemented inside of the set setter:
var canSave: Bool {
// This causes a compiler error:
// "'willSet' cannot be provided
// together with a setter"
set { /* ... */ }
willSet { /* ... */ }
}
// This is a better alternative:
var canSave: Bool {
set {
// Add code for willSet here,
// before a new value is set
canSave = newValue
}
}
Swift Getters and Setters
That’s it! By using get, set, willSet, and didSet you can implement getters and setters in Swift.