Access Control is an essential subject in Software Engineering overall, and it’s super important to consider this when building your application. In addition, access control is a standard subject across all programming languages, and in this article, we’re going to be covering access control in Swift.
Access Control uses keywords across properties, classes, structs, methods, enums and functions. It’s a way to tell the callee what access you have available. It’s best practice to consider this during your build because it means the application’s interface is clear and well understood.
It also allows you to restrict certain parts of your implementation and restrict access to the integration.
Access Control is like deciding what levels of security to have on your house; declaring your door as open
will mean leaving your door unlocked and anyone can walk in, whereas declaring your door as private
would imply that people can only gain access with a key. This key is only distributed to members of your family.
Swift Keywords
Most languages will define the access control with many keywords, which is no different in Swift. In Swift, we have five levels of access control:
open
andpublic
internal
file-private
private
Open & Public Access
This allows any of the enclosing modules to have access to this and any integrator that imports this module. You will typically use this when building a framework or module to define the interface. Open is the least restrictive access control, and it’s worth noting that declaring something open
will mean it’s available to your integrators to subclass and effectively override the implementation.
open class SwiftlyBank {}
Internal Access
This is the default access level if nothing is defined, for example:
class SwiftlyBank {}
This class would be described as internal
, but for brevity, you can always use the keyword internal
, which is always best practice, especially if you’re building a module that will be used outside your application.
The primary role of internal
is that it can be accessed throughout the module it’s defined in and not outside.
Also, a public variable can’t have an internal access level because you can’t be sure where this public variable will be used.
File Private Access
The file-private
access level is used to make an entire file private, thus allowing you to hide the implementation details of a specific file.
fileprivate class SwiftlyBank {}
This entire file SwiftlyBank is made file-private
, meaning everything inside is private
throughout your module.
It’s worth noting that fileprivate
only this file’s properties can define this class type when you make this class.
Private Access
The use of private
is probably going to be the access level you will use the most. Its purpose is to create a specific piece of functionality private to its entity. It means that you can use this private implementation within the declared type.
Let’s take a look at this example:
public class SwiftlyBank {
private func calculateDepositAmount(with amount: Float) -> Float {
// Calculation of deposit amount logic
}
public func makeDeposit(with amount: Float) {
let depositAmount = calculateDepositAmount(with: amount)
print(depositAmount)
}
}
public var bankManager = SwiftlyBank()
// Calculate Deposit Amount isn't accessible here and is private functionality
bankManager.calculateDepositAmount()
// Access the public function
bankManager.makeDeposit(with: 2.00)
The use of private
here is great because you’re likely you don’t want to expose the calculation logic to the outside world of your application.
If you’re building a single application, then you’re likely to leave the default access level internal
however, within this single application, you might want to take advantage of fileprivate
and private
to hide these implementation details accordingly.
Enum Types
When creating an enumeration type, all the individual cases will be given the same access level as the defining enum type.
private enum PaymentMethods {
case visa, mastercard, amex
}
In this example, all the cases will be private
because you have defined the PaymentMethods enum as private
.