Inappropriate coding practices - Swift

Inappropriate coding practices - Swift

Need

Enforcement of proper encapsulation in coding practices

Context

  • Usage of Swift 5.0 for iOS app development

Description

Non compliant code

        public class User {
    public var id: Int
    public var name: String
    public var email: String
    
    init(id: Int, name: String, email: String) {
        self.id = id
        self.name = name
        self.email = email
    }
}
        
        

In the above Swift code, we have a User class with three fields: id, name, and email. All the fields are defined as public. This is a violation of the encapsulation principle in object-oriented programming.

Encapsulation is one of the four fundamental OOP concepts. The other three are inheritance, polymorphism, and abstraction. Encapsulation is used to hide the values or state of a structured data object inside a class, preventing unauthorized parties' direct access to them.

However, in the above code, by declaring the fields as public, we are allowing direct access to them. This can lead to inappropriate modification of the data, which can potentially lead to data inconsistency and bugs that are hard to detect.

In Swift, the public access level enables 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. This means that any part of the code can directly modify the fields id, name, and email of the User class, which is not a recommended practice.

Steps

  • Step 1: Change the access modifiers of the fields in the User class from public to private.
  • Step 2: Create getter and setter methods for the fields to provide controlled access to them.
  • Step 3: Update the code that uses the User class to access the fields through the getter and setter methods instead of directly.

Compliant code

        public class User {
    private var id: Int
    private var name: String
    private var email: String
    
    init(id: Int, name: String, email: String) {
        self.id = id
        self.name = name
        self.email = email
    }
    
    public func getId() -> Int {
        return self.id
    }
    
    public func getName() -> String {
        return self.name
    }
    
    public func getEmail() -> String {
        return self.email
    }
    
    public func setId(id: Int) {
        self.id = id
    }
    
    public func setName(name: String) {
        self.name = name
    }
    
    public func setEmail(email: String) {
        self.email = email
    }
}
        
        

The above code fixes the vulnerability by changing the access modifiers of the fields in the User class from public to private. This respects the encapsulation principle by preventing direct access to the fields.

Getter and setter methods are created for each field to provide controlled access to them. The getter methods return the value of the respective field, while the setter methods set the value of the respective field.

The getId(), getName(), and getEmail() methods are used to get the values of the id, name, and email fields respectively. The setId(id: Int), setName(name: String), and setEmail(email: String) methods are used to set the values of the id, name, and email fields respectively.

Any code that uses the User class should now access the fields through these getter and setter methods instead of accessing the fields directly. This ensures that the fields are accessed and modified in a controlled manner, which helps to maintain the integrity of the data.

References