Swift - Custom Type Access Control


Swift has several different levels of access control.

To learn access control, we first need to know modules and source files.

A module is a chunk of code that is built, such as a library, or a build target such as an application.

Anything you import in Swift is a module.

A source file is the file that your Swift source code is being written in.

Modules and source files are the two chunks that access control operates on in Swift.

Swift defines five levels of access control.

They determine what information is accessible to which parts of the application:

open and public

open and public are very similar to one another:
all classes, methods, and properties are accessible by any part of the current module and any module that imports the current module.

internal data and methods are only accessible to the module in which they're defined.
internal is the default level of access control: if you don't specify the access control level, it's assumed to be internal.

fileprivate entities are only accessible to the source file in which they're declared.
This means that you can create classes that hide their inner workings from other classes in the same module.

private entities are only accessible to the current declaration scope.
this is the most restrictive access modifier.
This means you can create functions and objects that can hide their internals from everything else in the module and file.
You can declare a method or property as private inside a class, and nothing can ever access that method.

If your classes are marked as public, they can be used by other modules but only subclassed from within their own module.

open classes can be both used and subclassed by other modules.

You can't make a method more accessible than the class in which it's contained.

To specify the access level for a class, you add the appropriate keyword before the class keyword.

To define a public class called AccessControl, for instance, you'd write the following:

public class AccessControl { 

By default, all properties and methods are internal.

You can explicitly define an entity as internal if you want, but it isn't necessary:

internal var internalProperty = 1 

For classes defined as private or fileprivate-if you don't declare an access control level for a member, it's set as private or fileprivate, not internal.

You cannot specify an access level for a member of an entity that is more open than that of the entity itself.

If you declare an entity as private, it's only accessible from within the scope in which it's declared:

You can render a property as read-only by declaring that its setter is private:

private(set) var privateSetProperty = 234 

This means that you can freely read the property's value but nothing can change it outside of the class itself: 

If you use fileprivate instead of private as the access restriction level on your setters you can freely change the values inside the source file.

Related Topics