Access Control In Swift

Access Control restricts access to the parts of your code from other source files and modules. This feature enables you to hide the implementation details of your code and to specify a preferred class which that code can be accessed and used into.
You can declare specific access levels to individual types (classes, structures, and enumerations), as well as to properties, methods, initializers, and subscripts belonging to those types. Protocols can be restricted to a certain context, as can global constant, variables, and functions.

Modules and Source Files

Swift's access control model is based on the concept of 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. 
A source file is a single Swift source code file within a module. Although it's common to define individual types in separate source files, a single file can contain definitions for multiple types, function.

Access levels

Swift provides 5 different access levels for entities within your code. 
Access level is the highest access level or the least restrictive access level. You can subclass class marks as open. You typically use open access level when specifying the public interface to the framework.
Open and  enable code written in a source file to be used anywhere within a module as well as from another module that imports it. You can use classes marked  public but you can't subclass them.
Internal (default access level) 
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. You typically use internal access when defining an app's or a framework's internal structure. This is the default level of access.
Allows you to restrict the use of entity within its defining source file. Use file-private access to hide the implementation details of a specific piece of code functionality when those details are used within an entire file.
Private access restricts the use of an entity to enclosing declaration, and to extensions of that declaration that are in the same file. This is the most restrictive access level; i.e., a private stored property can only be used within its class.

Difference between Open and Public access

  1. Open access only applies classes and class members and an open class is accessible and subclassable outside of the defining module. An open class member is accessible and overridable outside of the defining module.
  2. Classes with public access, or any more restrictive access level, can be subclassed only within the module where they're defined.
  3. Class members with public access, or any more restrictive access level, can be overridden by subclasses only within the module where they're defined.
    1. //math addition and subtraction module     
    2. public func addition(){}    
    3. open func subtraction(){}    
    4. //module Mutliplication    
    5. public func multiply()    
    6. override func addition(){} // you will get an error    
    7. override func subtraction(){} // this will successfully override   
Public and Open come to play only between modules. Internal access mode will give public access throughout the same module.

Private members in Extention 

  1. Declare a private member in the original declaration and access that member from extensions in the same file.
  2. Declare a private member in one extension and access that member from another extension in the same file.
  3. Declare a private member in an extension and access that member from the original declaration in the same file.
  1. protocol SomeProtocol {  
  2.     func doSomething()  
  3. }  
  4. struct SomeStruct {  
  5.     private var privateVariable = 12  
  6. }  
  7. extension SomeStruct: SomeProtocol {  
  8.     func doSomething() {  
  9.         print(privateVariable)  
  10.     }  
  11. }