Skip to main content
  1. SwiftUI in 100 Days Notes/

Day 11 - Swift Struct - 2 : Access Control and Static Property & Method

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 print account.funds outside the struct, but only the deposit() and withdraw() methods could change the value.

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.

  1. Static code cannot be accessed from non-static code. static properties and methods cannot refer to non-static properties and methods.
  2. To access static code from non-static code, always use the name of the type, such as School.studentCount. We can also use Self to refer to the current type.

TIP 💡: self and Self 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 and Self. But it is similar to the naming used throughout Swift. We capitalize all our data types (Int, Double, Bool, etc.) so it makes sense that Self 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.

This article contains the notes I took for myself from the articles found at SwiftUI Day 11. Please use the link to follow the original lesson.