- Görkem Güray/
- SwiftUI in 100 Days Notes/
- Day 11 - Swift Struct - 2 : Access Control and Static Property & Method/
Day 11 - Swift Struct - 2 : Access Control and Static Property & Method
Table of Contents
Swift Access Control #
By default, Swift Structs have no limitations on access to property and method. But often this is not what we want. We may want to restrict external access to some property and method. Let’s look at our example to understand this problem;
struct BankAccount {
var funds = 0
mutating func deposit(amount: Int) {
funds += amount
}
mutating func withdraw(amount: Int) -> Bool {
if funds >= amount {
funds -= amount
return true
} else {
return false
}
}
}
The Struct above has deposit
and withdraw
methods representing deposits and withdrawals. Transactions can be done as follows.
var account = BankAccount()
account.deposit(amount: 100)
let success = account.withdraw(amount: 200)
if success {
print("Withdrew money successfully")
} else {
print("Failed to get the money")
}
But funds
property can be accessed and modified directly without any control. But we don’t want to access funds
directly. We want to access it only with deposit
and withdraw
methods.
account.funds -= 1000
Writing code like the above completely disables the logic we have built into the program.
To overcome this problem, we can tell funds
to be accessible only from within the struct it belongs to.
private var funds = 0
It is no longer possible to access funds
from outside the struct. But deposit
and withdraw
property can be accessed.
This is called access control. Access control allows you to control how the properties and methods of a struct are accessed from outside the struct.
Here are a few options Swift offers us;
private
: When we say “Don’t let anything outside of Struct use this”.fileprivate
: When we say “Don’t allow anything other than the current file to use this”.public
: When we say “Everyone, everywhere can use this”.private(set)
: means “Allow anyone to read this property, but only allow my methods to write to it”.- If we used this for
BankAcount
, it would mean that we could printaccount.funds
outside the struct, but only thedeposit()
andwithdraw()
methods could change the value.
- If we used this for
Note : If we use private
access control for one or more properties, we probably need to write our own initializer.
Why Do We Need Access Control? #
Access Control restricts access to different parts of our code. Okay, but why?
Sometimes access control is used in code that we don’t have, so we can’t remove access control. This is the case with Apple’s APIs, for example. While Apple allows us to use APIs, it puts restrictions on what we can and cannot do.
Of course we can remove access control in our own code. But this creates an illogical situation. With Access Control, we create a rule (or rules) and then tell Swift that we need to follow those rules.
Static Property and Method #
We can add properties and methods to a Struct. Each Struct instance has a copy of these properties and methods. This way, the method we call on one instance will not read the property of another instance.
Sometimes we may want to use a property or method directly, by adding it to the struct itself instead of to the instance of the struct. This technique is often useful for creating sample data and storing fixed data.
Let’s look at a simple example to understand static properties;
struct School {
static var studentCount = 0
static func add(student: String) {
print("\(student) joined the school.")
studentCount += 1
}
}
The studentCount
property with static
keyword and the add
method belong to the struct itself, not to the instances of the School
struct.
School.add(student: "Taylor Swift")
print(School.studentCount)
//OUTPUT:
//----------------------------------------
//Taylor Swift joined the school.
//1
Even though we didn’t create any instance of School
, we were able to use add()
and studentCount
directly from the struct, because they are both static, meaning they don’t exist uniquely in instances of the struct.
This also explains why we can change the studentCount
property with a method that is not marked as mutating
. mutating
is only required for struct instances that are created as constants, whereas there is no instance when add()
is called.
There are two rules when using static and non-static properties and methods with each other.
- Static code cannot be accessed from non-static code. static properties and methods cannot refer to non-static properties and methods.
- To access static code from non-static code, always use the name of the type, such as
School.studentCount
. We can also useSelf
to refer to the current type.
TIP 💡:
self
andSelf
mean different things;
self
refers to the current value of struct.Self
refers to the current type.It’s easy to forget the difference between
self
andSelf
. But it is similar to the naming used throughout Swift. We capitalize all our data types (Int
,Double
,Bool
, etc.) so it makes sense thatSelf
should also be capitalized.
Static Usage Examples #
Example-1:
Static can be used to keep common data in an application organized.
struct AppData {
static let version = "1.3 beta 2"
static let saveFilename = "settings.json"
static let homeURL = "https://www.hackingwithswift.com"
}
For example, if I need the version number anywhere in my application, I can access this information as AppData.version
.
Example-2:
It can be used to create instances of Structs. We can use live previews while developing the application in SwiftUI. Live previews give better results with sample data.
struct Employee {
let username: String
let password: String
static let example = Employee(username: "cfederighi", password: "hairforceone")
}
When we need an instance of Employee
, we can use Employee.example
.
100 Days of SwiftUI Checkpoint - 6 #
You can also read this article in Turkish.
Bu yazıyı Türkçe olarak da okuyabilirsiniz.