We’ve arrived at day 11 of the 100 Days of SwiftUI course. Today was fairly short, but still very interesting and useful. Yesterday, we tackled structs and how to use them within our programs. Today, we’re expanding on structs with access control, static properties and methods.
Access control for structs in SwiftUI
The structs we created yesterday were all publicly accessible. That is to say, you can access the structs variable properties and change them wherever you liked in your program. Today, we learned how to restrict this, so that a property can only be modified by a method within the struct.
Why is this necessary? Well, let’s say we have a struct for a bank account that had a property for the funds. We don’t want the funds to be freely changed around. That’s why we use access control to limit access to the funds property. For more on the matter, check out Paul’s article.
struct BankAccount {
let clientName: String
private(set) var funds: Int
mutating func depositFunds (depositAmount: Int) {
funds += depositAmount
print("You have deposited \(depositAmount). You're new balance is \(funds)")
}
mutating func withdrawFunds (withdrawalAmount: Int) {
if funds >= withdrawalAmount {
print("You are withdrawing \(withdrawalAmount). You'll have \(funds-withdrawalAmount) left after the withdrawal")
funds -= withdrawalAmount
} else {
print("You do not have enough funds to withdraw \(withdrawalAmount). You currently have \(funds).")
}
}
}
var maverickAccount = BankAccount(clientName: "Maverick", funds: 3200)
maverickAccount.depositFunds(depositAmount: 4800)
maverickAccount.withdrawFunds(withdrawalAmount: 2500)
maverickAccount.withdrawFunds(withdrawalAmount: 6000)
/* You have deposited 4800. You're new balance is 8000
You are withdrawing 2500. You'll have 5500 left after the withdrawal
You do not have enough funds to withdraw 6000. You currently have 5500. */
Static properties and methods
Sometimes, you’ll want to add a property or a method to a struct itself, and not to an instant of a struct. You’re probably thinking: what’s the point? Well, I thought the same. To no one’s surprise, Paul has an article covering a few examples.
struct School {
let name: String
static var studentCount: Int = 0
static func addStudent (student: String) {
print("\(student) has joined the school!")
studentCount+=1
}
}
School.addStudent(student: "Maverick")
School.addStudent(student: "Jace")
School.addStudent(student: "Sharon")
print("The current student count is \(School.studentCount)!")
/* Maverick has joined the school!
Jace has joined the school!
Sharon has joined the school!
The current student count is 3! */
SwiftUI checkpoint 6
We ended today with another checkpoint! The challenge:
To check your knowledge, here’s a small task for you: create a struct to store information about a car, including its model, number of seats, and current gear, then add a method to change gears up or down. Have a think about variables and access control: what data should be a variable rather than a constant, and what data should be exposed publicly? Should the gear-changing method validate its input somehow?
I was quite quick to come to a solution. I ended up refining a bit more and while I am sure there are more and shorter ways to solve it, I was quite happy with what I came up with, as I feel it implements what we’ve learned up until now quite well. Feel free to sound off in the comments if you disagree though!
struct Car {
public let model: String
public let numberOfSeats: Int
private(set) var currentGear: Int
mutating func shiftGearUp () {
if currentGear+1 > 10 {
print("You're already in \(currentGear) which is the maximum gear!")
} else {
print("Time to go faster! Shifting from \(currentGear) to \(currentGear+1)!")
currentGear += 1
}
}
mutating func shiftGearDown () {
if currentGear-1 < 0 {
print("You're in neutral, you can't shift down!")
} else {
print("Time to slow down a bit! Shifting gears from \(currentGear) to \(currentGear-1)!")
currentGear -= 1
}
}
// Custom initializer is not needed in this case, but I made it just for practicing purposes
init(model: String, numberOfSeats: Int, currentGear: Int) {
self.model = model
self.numberOfSeats = numberOfSeats
self.currentGear = currentGear
}
}
var tesla = Car(model: "Model X", numberOfSeats: 5, currentGear: 0)
print(tesla)
tesla.shiftGearUp()
tesla.shiftGearUp()
tesla.shiftGearUp()
tesla.shiftGearUp()
tesla.shiftGearUp()
tesla.shiftGearDown()
tesla.shiftGearDown()
tesla.shiftGearDown()
tesla.shiftGearDown()
tesla.shiftGearDown()
tesla.shiftGearDown()
tesla.shiftGearUp()
tesla.shiftGearUp()
tesla.shiftGearUp()
tesla.shiftGearUp()
tesla.shiftGearUp()
tesla.shiftGearUp()
tesla.shiftGearUp()
tesla.shiftGearUp()
tesla.shiftGearUp()
tesla.shiftGearUp()
tesla.shiftGearUp()
/*Output:
Car(model: "Model X", numberOfSeats: 5, currentGear: 0)
Time to go faster! Shifting from 0 to 1!
Time to go faster! Shifting from 1 to 2!
Time to go faster! Shifting from 2 to 3!
Time to go faster! Shifting from 3 to 4!
Time to go faster! Shifting from 4 to 5!
Time to slow down a bit! Shifting gears from 5 to 4!
Time to slow down a bit! Shifting gears from 4 to 3!
Time to slow down a bit! Shifting gears from 3 to 2!
Time to slow down a bit! Shifting gears from 2 to 1!
Time to slow down a bit! Shifting gears from 1 to 0!
You're in neutral, you can't shift down!
Time to go faster! Shifting from 0 to 1!
Time to go faster! Shifting from 1 to 2!
Time to go faster! Shifting from 2 to 3!
Time to go faster! Shifting from 3 to 4!
Time to go faster! Shifting from 4 to 5!
Time to go faster! Shifting from 5 to 6!
Time to go faster! Shifting from 6 to 7!
Time to go faster! Shifting from 7 to 8!
Time to go faster! Shifting from 8 to 9!
Time to go faster! Shifting from 9 to 10!
You're already in 10 which is the maximum gear! */
And that was it for day 11! Learning about structs was a lot of fun and I can see how they’ll be very useful when programming. Up tomorrow are classes, inheritance, and checkpoint 7. Time to recharge and charge on ahead!
100 Days of SwiftUI – Day 11 – Structs, Part 2