Swift Access Control
In Swift, Access Control is a feature that allows you to control the visibility and accessibility of your code entities, such as types, functions, properties, and protocols. This means that you can restrict certain parts of your code from being accessed by others outside of a defined scope, which can help ensure security, encapsulation, and maintainability.
Swift Access Control Types
Swift has five types of access control levels that you can use to restrict the visibility of your code entities:
open
: The most permissive access level, allows the entity to be accessed by any code in any module.public
: Allows the entity to be accessed by any code in the same module or by external modules that import the module where the entity is defined.internal
: The default access level, allows the entity to be accessed within the same module where it is defined, but not by code in other modules.fileprivate
: Allows the entity to be accessed within the same file where it is defined.private
: The most restrictive access level, allows the entity to be accessed only within the same scope where it is defined, such as a function or a class.
Access Control for Function Types
You can apply access control levels to function types in Swift by specifying the access level before the func
keyword. For example:
1public func myFunction() { 2 // ... 3}
In this example, the myFunction
function has a public
access control level, which means it can be accessed by any code in the same module or by external modules that import the module where the function is defined.
Access Control for Enumeration Types
You can apply access control levels to enumeration types in Swift by specifying the access level before the enum
keyword. For example:
1public enum MyEnum { 2 // ... 3}
In this example, the MyEnum
enumeration has a public
access control level, which means it can be accessed by any code in the same module or by external modules that import the module where the enumeration is defined.
Access Control for SubClasses
You can use access control levels to restrict which subclasses can access a class or a method by specifying the access level before the class or method keyword. For example:
1class MyClass { 2 internal func myMethod() { 3 // ... 4 } 5} 6 7internal class MySubclass: MyClass { 8 override func myMethod() { 9 // ... 10 } 11}
In this example, the MyClass
has an internal
access control level, which means it can be accessed within the same module where it is defined, but not by code in other modules. The MySubclass
has an internal
access control level as well, which means it can access MyClass
's internal
methods, but not private
methods.
Access Control for Constants and Variables
You can apply access control levels to constants and variables in Swift by specifying the access level before the let
or var
keyword. For example:
1public let myConstant = 42 2fileprivate var myVariable = "Hello, world!"
In this example, myConstant
has a public
access control level, which means it can be accessed by any code in the same module or by external modules that import the module where the constant is defined. myVariable
has a fileprivate
access control level, which means it can be accessed within the same file where it is defined.
Access Control for Properties and Subscripts
Properties and subscripts can also have access control in Swift. We can apply access control to properties and subscripts by specifying their access level before their declaration.
Here's an example:
1public class MyClass { 2 public var myPublicProperty: String 3 internal var myInternalProperty: String 4 fileprivate var myFilePrivateProperty: String 5 private var myPrivateProperty: String 6 7 public subscript(index: Int) -> Int { 8 // getter and setter implementation 9 } 10}
Getters and Setters
We can also specify access control for the get
and set
methods of a property using the get
and set
keywords, respectively.
Here's an example:
1public class MyClass { 2 private var myPrivateProperty: String 3 4 public var myPublicProperty: String { 5 get { 6 return myPrivateProperty 7 } 8 set(newValue) { 9 myPrivateProperty = newValue 10 } 11 } 12}
Access Control for Initializers and Default Initializers
We can also apply access control to initializers and default initializers by specifying their access level before their declaration.
Here's an example:
1public class MyClass { 2 private var myPrivateProperty: String 3 4 public init() { 5 myPrivateProperty = "Hello, World!" 6 } 7 8 fileprivate init(text: String) { 9 myPrivateProperty = text 10 } 11 12 private init(number: Int) { 13 myPrivateProperty = String(number) 14 } 15}
Access Control for Protocols
We can apply access control to protocols by specifying their access level before their declaration.
Here's an example:
1public protocol MyProtocol { 2 func myFunction() 3} 4 5fileprivate protocol MyFilePrivateProtocol { 6 func myFunction() 7}
Access Control for Extensions
We can apply access control to extensions by specifying their access level before their declaration.
Here's an example:
1public class MyClass { 2 private var myPrivateProperty: String 3} 4 5fileprivate extension MyClass { 6 func myFunction() { 7 // implementation 8 } 9}
Access Control for Generics
We can apply access control to generic types, methods, and protocols by specifying their access level before their declaration.
Here's an example:
1public class MyClass<T> { 2 private var myPrivateProperty: T 3} 4 5fileprivate protocol MyFilePrivateProtocol { 6 associatedtype MyType 7 func myFunction(myArg: MyType) 8}
Access Control for Type Aliases
We can also apply access control to type aliases by specifying their access level before their declaration.
Here's an example:
1public class MyClass { 2 private var myPrivateProperty: String 3 4 public typealias MyTypeAlias = String 5}
Swift Encoding and Decoding
Swift also provides a built-in way to encode and decode data in a type-safe manner using the Codable
protocol. We can use access control to specify which properties should be encoded and decoded.
Here's an example:
1public struct MyStruct: Codable { 2 private var myPrivateProperty: String 3 4 public var myPublicProperty: String 5 6 enum CodingKeys: String, CodingKey { 7 case myPublicProperty 8 } 9}
In this example, only the myPublicProperty
property will be encoded and decoded. The myPrivateProperty
property is hidden from the encoding and decoding process.