Access control restricts access to parts of your code from code in other source files and modules.
This feature enables you to hide the implementation details of your code and specify a preferred interface through which others can interact.
Properly managing access control is a crucial aspect of building secure, encapsulated architectures.
Swift provides five distinct access levels for entities within your code, ranging from most open to most restrictive:
open: The least restrictive. Allows access and subclassing from completely different modules.public: Allows access from other modules, but prevents subclassing or overriding outside the defining module.internal: The default level. Allows access anywhere within the same module/target, but restricts it outside the module.fileprivate: Restricts the use of an entity to its own defining source file.private: The most restrictive. Restricts the use of an entity to the enclosing declaration, and to extensions of that declaration that are in the same file.private KeywordWhen you build a class or struct, you often create variables that are meant to manage internal state.
You don't want outside objects messing with this internal data directly. You protect it using private.
struct BankAccount {
// This property cannot be read or modified outside this struct
private var balance: Double = 0.0
mutating func deposit(amount: Double) {
balance += amount
print("Deposited. Current balance hidden securely.")
}
}
var myAccount = BankAccount()
myAccount.deposit(amount: 100)
// print(myAccount.balance) // This will cause a compiler ERROR!
Sometimes, you want everyone to be able to read a property, but you only want the object itself to be allowed to modify it.
You can achieve this easily using private(set).
struct Scoreboard {
// Anyone can read this, but only methods inside Scoreboard can change it
private(set) var highScore = 0
mutating func updateScore(newScore: Int) {
if newScore > highScore {
highScore = newScore
}
}
}
var board = Scoreboard()
board.updateScore(newScore: 50)
print(board.highScore) // Perfectly fine to read!
// board.highScore = 100 // ERROR! Cannot mutate externally.
The guiding principle of access control in Swift is: No entity can be defined in terms of another entity that has a lower (more restrictive) access level.
For example, a public variable cannot be defined as having an internal or private type.
What is the default access control level applied to classes and variables in Swift if you don't explicitly write one?