Everything you need to know about Swift Access Modifiers

Masih Tabrizi
3 min readFeb 11, 2018


Swift 4 provides five different access levels. There are always some methods or variables in Object Oriented Programming that should be private or final. This enables you to hide the implementation details of your code which is the main purpose of these keywords:


Open is the least restrictive access level. It enables an entity to be used outside the defining module (target) and it can be subclassed or overridden from any module that imports the module where they’re defined. This is why you can override or subclass UITableView when you import it from UIKit.


Like open access level, public access level enables an entity to be used outside the defining module (target). But open access level allows us to subclass it from another module where in public access level, we can only subclass or override it from within the module it is defined. The public defined entity can be subclassed or overridden only within the module where they’re defined.

open vs. public

// First.framework – A.swift
open class A {}
// First.framework – B.swift
public class B: A {} // ok
// Second.framework – C.swift
import First
class C: A {} // ok
// Second.framework – D.swift
import First
class D: B {} // error: B cannot be subclassed

A class defined as open can be subclassed from other modules. Also, they allow members from other modules to use and override them. public allows classes from other module to use them, but not to inherit them. Also, they allow members from other modules to use them, but not to override them.


An internal defined can be accessed anywhere within the same module (target) they are defined but not from anywhere outside. It is good to know that this is the default access level.

// First.framework – A.swift
internal struct A {}

// First.framework – B.swift
A() // ok

// Second.framework – C.swift
import First
A() // error: A is unavailable

This is very helpful when your developing a library (framework), you can use internal to hide library structure and provide interfaces for users.


Restricts the use of an entity to its defining source file.


Private access restricts the use of an entity to the enclosing declaration, and to extensions of that declaration that are in the same file.


As of Swift 3 you can add final to any access level, except open (since open is for providing overriding and subclassing access), to prevent subclassing or overriding of a class method or property.

Swift 4, extensions, and a new private access

Swift 4 has changed the scope of private access reducing the need to use fileprivate for extension access.

Before swift 4, private access level didn’t allow the use of a class member inside the extension of same class:

class A {
private var flag = false
extension A {
func isFlagSet() -> Bool {
return flag
// Error in Swift 3
// works fine in Swift 4

In Swift 3 the problem is that the private access level restricts access to the property to the enclosing class declaration. The extension is not allowed access even though it is in the same source file. The solution is to switch the access level to fileprivate.

Swift 4 lets us to use private access to include extensions which reduce use of fileprivate for properties that are being accessed within the extensions.


public is accessible (only accessible, no option for subclassing/overriding) outside the defining module. open however offers both accessibility and overridability even outside its module. internal is not even accessible outside its own module. fileprivate allows use only within the defining source file while private allows use only from the enclosing declaration and new in Swift 4, to any extensions of that declaration in the same source file.

Further Study

Access Control and protected
Access Control
Does Swift have access modifiers?