Swift. Declaring Private Functions in Internal Protocol

Swift. Declaring private functions in internal protocol

From Apple's docs it looks like the only way to achieve what you are trying to do is to implement 2 protocols - one internal, and one private, as Apple states "You cannot set a protocol requirement to a different access level than the protocol it supports."

Is there a way to declare protocol property as private?

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

Are private swift protocols possible?

In Swift private means: visible within the current source file.

A private Type could conform to a private protocol, look here:

private protocol Animal { }
private class Dog: Animal { }

class Zoo {
private var animals = [Animal]()
var count : Int { return animals.count }
}

Here, Animal and Dog are visible only within the current files. However, they are used by Zoo which has internal visibility and exposes the count of the animals to the whole module.

Public class with a private functions by default

If you really wanted to you could use the following for properties:

private var property1: String, property2: String

You can't do the same for methods. Maybe one day this will be supported:

private extension Car {
func action() {}
}

Implementing a public protocol with internal class in swift

ThingImpl is an internal class. So it will override the accessibility of the public x variable, effectively making this variable internal. So, set the accessibility of this variable to public is redundant.

Implement a public method that rely on a private property in Swift using protocols

Following this discussion from Swift forum, there are two ways to solve the issue.

First one is straightforward:

/// The publically visible capabilities.
public protocol SameModifierProtocol {
func modifier(x: Int) -> SameModifierProtocol
}
/// The internal requirements on which the default implementation relies.
internal protocol SynthesizedSameModifierProtocolConformance:
SameModifierProtocol {
var x: Int { get set }
}
/// The default implementation.
extension SynthesizedSameModifierProtocolConformance {
public func modifier(x: Int) -> SameModifierProtocol{
var s = self
s.x = x
return s
}
}

/// Conforms to the public protocol
/// and requests the default implementation from the internal one.
/// Clients can only see the public protocol.
public struct Component: SynthesizedSameModifierProtocolConformance {
internal var x: Int = 0
public init() {}
}

The second involves an unofficial feature @_spi, that allows to make implementation details unexposed in a public protocol:

public protocol SameModifierProtocol {
@_spi(SameModifier) var x: Int { get set }
}

extension SameModifierProtocol {
public func modifier(x: Int) -> Self {
var s = self
s.x = x
return s
}
}

public struct Component: SameModifierProtocol {
@_spi(SameModifier) public var x: Int = 0
public init() {}
}


Related Topics



Leave a reply



Submit