Access Control

Swift’s ability to provide different access levels to types, properties, methods initializers, and subscripts is the reason why techniques like Encapsulation work at all in Swift - so it’s a fairly important feature. It also lets you expose public interfaces and gives you the ability to hide complex implementation details, so basically the foundation of good API design.

Access Control provides five different access levels

  1. private
  2. fileprivate
  3. internal
  4. public
  5. open

Before we cover them in detail we first need to understand the difference between Modules and Source Files.

A module is a single unit of code distribution—a framework or application that is built and shipped as a single unit and that can be imported by another module with Swift’s import keyword. [1]

Each build target (such as an app bundle or framework) in Xcode is treated as a separate module in Swift. If you group together aspects of your app’s code as a stand-alone framework—perhaps to encapsulate and reuse that code across multiple applications—then everything you define within that framework will be part of a separate module when it’s imported and used within an app, or when it’s used within another framework.[2]

A source file is a single Swift source code file within a module (in effect, a single file within an app or framework). Although it’s common to define individual types in separate source files, a single source file can contain definitions for multiple types, functions, and so on.[3]

  1. Private access is the most restrictive. Entities with a private access level can only be accessed within the entity they are defined in, as well as any nested type within them. Use private access to hide implementation details from the outer scope.

  2. Closely related to private is fileprivate. Entities with fileprivate access level can be accessed by entities that are defined in the same source file. Use fileprivate access to hide the implementation details of a specific piece of functionality when those details are used within an entire file. This can be useful when creating fileprivate extensions of existing types.

  3. Internal access is the default access level in Swift. Entities with internal access level can be accessed by all entities that are defined in the same module.

  4. Entities with public and open access, can be used by all entities within any source file from their defining module. Effectively, public/open declares the public interface for the module, which means that the entities are also accessible from other modules that import their defining module. However, there is a slight difference between public and open:

  • Classes and members of classes with public access level can be subclasses/overwritten only within the module where they’re defined in

  • Classes and members of classes with open access level can be subclassed/overwritten within any module that imports the module where they’re defined


[1] Apple Inc. “Swift.org.” Access Control - The Swift Programming Language (Swift 5), docs.swift.org/swift-book/LanguageGuide/AccessControl.html.
[2] ibid.
[3] ibid.

Written on May 19, 2019