Search code examples
swiftprotocolsaccess-control

Is there a way to declare protocol property as private?


I want to conform to a protocol, as well as to hide its conformed properties to be accessed (declare them as private).

Consider the following:

protocol P {
    var value: String { get }

    init(value: String)
}

class C: P {
    var value: String

    required init(value: String) {
        self.value = value
    }
}

I would create a C object:

let myObject = C(value: "Hello World")
myObject.value = "New Value"

Based on that I have 2 questions:

Now, if I tried to declare value as private:

private var value: String { get }

the compiler will throw an error:

'private' modifier cannot be used in protocols

with a fix suggestion to replace the private with internal.

How can I prevent value from being accessible by saying myObject.value? if there is no way, what's the reason of this limitation?


Solution

  • Conforming to

    protocol P {
        var value: String { get }
    
        init(value: String)
    }
    

    requires a gettable property value with default access. If write access to the property in the conforming class should be restricted to the class itself then you can declare it as in Swift readonly external, readwrite internal property:

    class C: P {
        private(set) var value: String
    
        required init(value: String) {
            self.value = value
        }
    }
    
    let myObject = C(value: "Hello World")
    print(myObject.value) // OK
    myObject.value = "New Value" // Error: Cannot assign to property: 'value' setter is inaccessible
    

    And if the property should only be set in initializers then make it a constant:

    class C: P {
        let value: String
    
        required init(value: String) {
            self.value = value
        }
    }
    
    let myObject = C(value: "Hello World")
    print(myObject.value) // OK
    myObject.value = "New Value" // Error: Cannot assign to property: 'value' is a 'let' constant