# How to compute property values dynamically

Paul Hudson    @twostraws

Updated for Xcode 13.3

Structs can have two kinds of property: a stored property is a variable or constant that holds a piece of data inside an instance of the struct, and a computed property calculates the value of the property dynamically every time it’s accessed. This means computed properties are a blend of both stored properties and functions: they are accessed like stored properties, but work like functions.

As an example, previously we had an `Employee` struct that could track how many days of vacation remained for that employee. Here’s a simplified version:

``````struct Employee {
let name: String
var vacationRemaining: Int
}

var archer = Employee(name: "Sterling Archer", vacationRemaining: 14)
archer.vacationRemaining -= 5
print(archer.vacationRemaining)
archer.vacationRemaining -= 3
print(archer.vacationRemaining)``````

That works as a trivial struct, but we’re losing valuable information – we’re assigning this employee 14 days of vacation then subtracting them as days are taken, but in doing so we’ve lost how many days they were originally granted.

We could adjust this to use computed property, like so:

``````struct Employee {
let name: String
var vacationAllocated = 14
var vacationTaken = 0

var vacationRemaining: Int {
vacationAllocated - vacationTaken
}
}``````

Now rather than making `vacationRemaining` something we can assign to directly, it is instead calculated by subtracting how much vacation they have taken from how much vacation they were allotted.

When we’re reading from `vacationRemaining`, it looks like a regular stored property:

``````var archer = Employee(name: "Sterling Archer", vacationAllocated: 14)
archer.vacationTaken += 4
print(archer.vacationRemaining)
archer.vacationTaken += 4
print(archer.vacationRemaining)``````

This is really powerful stuff: we’re reading what looks like a property, but behind the scenes Swift is running some code to calculate its value every time.

We can’t write to it, though, because we haven’t told Swift how that should be handled. To fix that, we need to provide both a getter and a setter – fancy names for “code that reads” and “code that writes” respectively.

In this case the getter is simple enough, because it’s just our existing code. But the setter is more interesting – if you set `vacationRemaining` for an employee, do you mean that you want their `vacationAllocated` value to be increased or decreased, or should `vacationAllocated` stay the same and instead we change `vacationTaken`?

I’m going to assume the first of those two is correct, in which case here’s how the property would look:

``````var vacationRemaining: Int {
get {
vacationAllocated - vacationTaken
}

set {
vacationAllocated = vacationTaken + newValue
}
}``````

Notice how `get` and `set` mark individual pieces of code to run when reading or writing a value. More importantly, notice `newValue` – that’s automatically provided to us by Swift, and stores whatever value the user was trying to assign to the property.

With both a getter and setter in place, we can now modify `vacationRemaining`:

``````var archer = Employee(name: "Sterling Archer", vacationAllocated: 14)
archer.vacationTaken += 4
archer.vacationRemaining = 5
print(archer.vacationAllocated)``````

SwiftUI uses computed properties extensively – you’ll see them in the very first project you create!

SPONSORED Spend less time managing in-app purchase infrastructure so you can focus on building your app. RevenueCat gives everything you need to easily implement, manage, and analyze in-app purchases and subscriptions without managing servers or writing backend code.

Sponsor Hacking with Swift and reach the world's largest Swift community!

BUY OUR BOOKS

Was this page useful? Let us know!

Average rating: 4.2/5

You are not logged in

Link copied to your pasteboard.