Published on

Basics of Swift Access Control

Authors
Swift Access Control her image

When writing stuctures, class and functions you need to let other code or even other developers know what is available and what is not. This is done by access control prefixing with public, open, internal, private, and fileprivate. Access control is another foundational concept that eluded me for years while learning the Swift language.

This is a another post in a series intended as a personal growth exercise. As I learn and digest new things, I want to write about them to solidify my understanding.

Feynman →

These features can restrict team members from accessing, extending or overriding the original implementation of some code. It's very useful when creating a framework or library that is intended to be shared openly among a developer community.

Let's look at module; an individual unit of code distribution, e.g. your app.

open and public are used to declare code accessibility across different modules.

internal, fileprivate and private are used at the Swift file level.

private

// Foo.swift
struct FooStruct {
    private let privateStr = "privateStr"

    func fooPrintFunc() {
        print("\(privateStr)")
    }
}

struct FooStructOne {
    var fooStruct = FooStruct() {
        didSet {
            fooStruct.privateStr
        }
    }
}

// Bar.swift
extension FooStruct {
    func fooFunc() {
        print("\(privateStr)")
    }
}

Given the example above, FooStructOne tries to access the setter of FooStruct private property, but cannot because of private access control. Similarly, the FooStruct extension in Bar.swift cannot extend and print privateStr in Foo.swift because FooStruct is not contained in the same Swift file.

private means declared code such as class, struct, enum, property and method can only be accessed withing the current scope and enclosed type. Only extensions within the same Swift file can access private declared code.

The scope of extension can only access those private properties when they are declared in the same file of the extended, declared code (class, struct, enum, property, or method, etc.).

fileprivate

struct FooStruct {
    private let privateStr = "privateStr"
}

extension FooStruct {
    func fooFunc() {
        print("\(privateStr)")
    }
}

Each Swift file can contain classes, structs, enums, etc. fileprivate means the code can only be accessible within the same Swift file.

internal

is the default access control in the Swift language. Marking declared code as internal means it can be accessed within the same module (app) freely. Developers can even subclass, extend, and override classes, structs, properties and methods.

public

Marking declared code as public means that it can be accessed across different modules and files, but it cannot be subclassed. A good example is the init function of a class in order to prevent abnormal initialization made by other developers.

open

The most unrestricted access control level. All open declared code can be accessed and subclassed with no restriction among modules. The open function and properties within the class can even be overriden.

For example, UICollectionView is an open class in that developers can create a custom UICollectionView.

Summary

Access Control provides a great tool for developers to restrict access rights of declared code. It is useful when you are developing and SDK or API for other developers to implement. They include:

  1. private - Most restricted. Properties can only be accessed within the current enclosing type.
  2. fileprivate - Can only be accessed within the same file
  3. internal - This is the default access control and can be accessed within the same module freely.
  4. public - Class can be accessed across different modules (app module and 3rd party library) but cannot be subclassed and its content cannot be overridden.
  5. open - The most unrestricted access control and other developers can subclass it and override those open properties.

In order to develop a safe and stable app, it is recommended to consider private first, and then think twice before loosening up the access control.

Reference

Apple Documentation - Access Control in the Swift Language