Introduction to Access Controls in Swift

Posted on Jan 30, 2021

In Swift language, Access Controls are features that restricts access over your code and module. You can specify them over classes, structs, modules and variables. There are 5 different Access Level currently and let’s check out how to use them?

Open Access

In Swift world, you must heard about modules, I mean not the folder represented modules like in a single Xcode application. I mean the module is that may 3rd party library from Cocoapods, Swift Package Manager or Carthage. So you can reach the classes, structures, variables etc. of the modules by Public Access Modifier but you cannot override them. So you cannot derive a subclass from that. Open Access is the highest access level that Apple says.

For example, there’s an Logger class in the module and you’ve imported the module to your own project. Then you decide to override the Logger because of your custom project structure (maybe you decide to conform a POP style thing, or something crazy and beatiful). So that class must be open as level if you want to override it.

Public Access

As we mentioned before in Open Access, it’s the highest access level. So what’s difference between public and open? What’s public? Public is the 2nd highest access level modifier after the Open modifier. So you can use it everywhere when you wanted to make a variable, class or structure public to anyone. When you compare it with open access level, here is tips:

  • If module classes, structures, variables etc. has public access level you can reach that but you cannot override them. That’s the key difference between open and public.

Internal Access

Internal access level is such a default access schema for the Swift language. It defines that you can reach and access enabled entities ( classes, structures, variables etc. ) that if and only with the same module.

For example you’ve created an Xcode iOS project and here is the basic example of the UIViewController.

class ViewController: UIViewController {
    var simpleVariable: Int = 14
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
}

As you can see there’s no access level modifier in the ViewController. This is pure. When you looked at the file with Àssistant Editor you can see the real modifiers of the class and it’s variables and functions.

internal class ViewController : UIViewController {

    internal var simpleVariable: Int

    override internal func viewDidLoad()
}

So the default entities takes internal in Swift language. In your project ViewController is accessible for everything, but just in your project module. If you create any other module (target etc.) for that project ViewController is not accessible for that modules.

Private Access

Private is an access level in Swift which the lowest access level with most restrictive as Apple says in the documentation. If a variable, structure, classes or anything takes private access no one can reach the this entity but just in defined entity.

class ViewController: UIViewController {
    private var simpleVariable: Int = 14
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    public func get() -> Int {
        return simpleVariable
    }
}

As you see simpleVariable is private. It means simpleVariable is not reachable from the instance of the ViewController so this code gives error because of the trying to access to simpleVariable

var instance = ViewController()
instance.simpleVariable

but you can reach to simpleVariable with a helper public class like as you can see in example get() function. private variable / method is reachable in the same entity.

Fileprivate Access

Fileprivate access is the most interesting access level I’ve ever heard. It restricted entity (variable, class, struct, enum etc.) over the file that it created. So let’s think you’ve created a helper class named Logger and it’s access level let’s be fileprivate. So Logger is just accessible for that file and works like Public in the file but just that file. For another files it cannot be reached because of private access.

Private is an access level in Swift which the lowest access level with most restrictive as Apple says in the

//
// file:  ViewController.swift
//

import UIKit

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()   
        let a = 12.canDividedBy2
    }
}


fileprivate extension Int {
    var canDividedBy2: Bool {
        return self % 2 == 0
    }   
}

As you can see above, we declare a fileprivate extension. It means that extension works like public in the file of ViewController.swift, and other files it’s behaviour is totaly restricted as private. So you cannot reach canDividedBy2 method in other files but this file its reachable.

With this ideas we can sum up the Access Levels from Most Restricted to Least Restricted as below.

Private -> Fileprivate -> Internal -> Public -> Open

I hope you like the content of the blog and hope you like it.

Feel free to reach me.