cft

Access Control: Part 1

The Resistance of Swift


user

Dhayaalan Raju

2 years ago | 5 min read

What is access control?

As the name suggests Access control restricts access to parts of the code from other source files and modules.

Why to use access control?

This feature enables to hide the implementation details of the code and specifies a preferred interface through which that code can be accessed and used.

These specific access levels can be assigned to individual types like classes, structures, and enumerations, etc.

Topics covered are,

  1. Modules and Source Files
  2. Access Levels
  3. Access Control on Functions
  4. Access Control on Enumerations
  5. Access Control on Subclassing
  6. Access Control on Constants, Variables, Properties, and Subscripts

1. Modules and Source Files

To have a clear understanding of access controls it is important to know about these two things because swift’s access control model is based on the concept of modules and source files.

  • 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.
  • source file is a single Swift source code file within a module it contains definitions for multiple types, functions, and so on.

2. Access Levels

Swift provides five different access levels for entities within the code. These access levels are relative to the source file in which an entity is defined, and also relative to the module that source file belongs to.

  • Open access and Public access enable entities to be used within any source file from their defining module, and also in a source file from another module that imports the defining module.
    Open access applies only to classes and class members, and it differs from public access by allowing code outside the module to subclass and override.
  • Internal access enables entities to be used within any source file from their defining module, but not in any source file outside of that module.
  • File-private access restricts the use of an entity to its own defining source file. File-private access is used to hide the implementation details of a specific piece of functionality when those details are used within an entire 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. Private access is used to hide the implementation details of a specific piece of functionality when those details are used only within a single declaration.

Open access is the highest access level and private access is the lowest access level.

Here,

  • highest meaning least restrictive
  • lowest meaning most restrictive

Default Access Levels

All entities in the code (with a few specific exceptions) have a default access level of internal unless an explicit access level is specified.

As a result, in many cases, an explicit access level is not necessary for the code.

Access Control Syntax

The syntax for defining the access level for an entity is done by placing one of the openpublicinternalfileprivate, or private modifiers at the beginning of the entity’s declaration.

Some examples(some of these examples are used throughout this blog) are,

public class SomePublicClass {}
internal class SomeInternalClass {}
private class SomePrivateClass {}
public var somePublicVariable = 0
internal let someInternalConstant = 0
private func somePrivateFunction() {}

The default access level is internal, as mentioned above. This means that SomeInternalClass and someInternalConstant can be written without an explicit access-level modifier, and will still have an access level of internal:

class SomeInternalClass {} // implicitly internal
let someInternalConstant = 0 // implicitly internal

3. Access Control on Functions

The access level must be specified explicitly as part of the function’s definition if the function’s calculated access level doesn’t match the contextual default.

Consider this scenario, the example below defines a global function called someFunction(), without providing a specific access-level modifier for the function itself.

The default access level internal does not apply here. In fact, someFunction() won’t compile as written below:

func someFunction() -> (SomeInternalClass, SomePrivateClass) {
// function implementation
}

The function’s return type is a tuple type composed of the custom classes declared above in the examples. One of these classes is defined as internal, and the other is defined as private. Therefore, the overall access level of the compound tuple type is private.

Because the function’s return type is private, the function’s overall access level is to be specified private in order to be valid.

private func someFunction() -> (SomeInternalClass, SomePrivateClass){
// function implementation
}

4. Access Control on Enumerations

The individual cases of an enumeration automatically belong to the same access level as the enumeration. A different access level cannot be specified for individual enumeration cases.

Consider this scenario, In the example below, the CompassPoint enumeration has an explicit access level of the public. The enumeration cases north, south, east, and west therefore also have an access level of the public.

public enum CompassPoint {
case north
case south
case east
case west
}

Raw Values and Associated Values

The types used for any raw values or associated values in an enumeration definition must have an access level at least as high as the enumeration’s access level. For example, you can’t use a private type as the raw-value type of an enumeration with an internal access level.

5. Access Control on Subclassing

In inheritance, the class which is inheriting properties, methods from another class is called a subclass and the class which contains properties, methods, and functions to inherit other classes is called a superclass.
To know more about inheritance click 
here.

Any class can be inherited that's defined in the same module as the subclass and it applies the same for any class which has the access control open that's defined in a different module.

A subclass can’t have a higher access level than its superclass-for example, you can’t write a public subclass of an internal superclass.

When it comes to overriding, For classes that are defined in the same module, any class member can be overridden that’s visible in a certain access context. For classes that are defined in another module, any open class member can be overridden.

An override can make an inherited class member more accessible than its superclass version.

In the example below, classA is a public class with a file-private method called someMethod(). classB is a subclass of classA, with a reduced access level of internal.

Nonetheless, classB provides an override of someMethod() with an access level of internal, which is higher than the original implementation of someMethod()

public class classA {
fileprivate func someMethod() {}
}
internal class classB: classA {
override internal func someMethod() {}
}

It’s even valid for a subclass member to call a superclass member that has lower access permissions than the subclass member, as long as the call to the superclass’s member takes place within an allowed access level context (that is, within the same source file as the superclass for a file-private member call, or within the same module as the superclass for an internal member call)

public class classA {
fileprivate func someMethod() {}
}
internal class classB: classA {
override internal func someMethod() {
super.someMethod()
}
}

Because superclass classA and subclass classB are defined in the same source file, it’s valid for the classB implementation of someMethod() to call super.someMethod().

6. Access Control on Constants, Variables, Properties, and Subscripts

If a constant, variable, property, or subscript makes use of a private type, then the constant, variable, property, or subscript must also be marked as private.

private var privateInstance = SomePrivateClass()

Upvote


user
Created by

Dhayaalan Raju

iOS Developer at Ivy Mobility


people
Post

Upvote

Downvote

Comment

Bookmark

Share


Related Articles