6

I am working on a framework in swift. I am creating a class which deals with BLE stuff in the framework. This class should be public as I need to access this class from external application which uses my framework. My class structure is a below:

public class MyClass: NSObject, CBCentralManagerDelegate {
}

Here MyClass is public, which confirms a public protocol CBCentralManagerDelegate. Compiler force me to declare it's delegate methods as public. So here is what my implementation looks like:

public class MyClass: NSObject, CBCentralManagerDelegate {
    public func centralManager(central: CBCentralManager, didConnectPeripheral peripheral: CBPeripheral) {

    }
    // I don't want delegate methods to be public, delegate  methods should be like: 
    //func centralManager(central: CBCentralManager, didConnectPeripheral peripheral: CBPeripheral) {

    //}
}

I have explore apple document here and a SO question here. I came to know that as my class and protocol both are public the methods should be public.

The problem with this is, an external application can easily create instance of my class and call this method, which my framework doesn't expect.

I would like to keep the delegate methods private so no one can call them manually.

What are the possible solution I have?

Iulian Onofrei
  • 9,188
  • 10
  • 67
  • 113
Kapil Choubisa
  • 5,152
  • 9
  • 65
  • 100
  • You can't avoid that. A protocol describes a *public* interface of your class. You can't just make it hidden. – Sulthan Dec 08 '15 at 11:35

1 Answers1

3

Trying to hide the methods of a public protocol in a public class doesn't make much sense, because it defeats the purpose of using protocols in the first place.

If you really need to hide them, you can add a private instance variable that will act as a delegate instead of the class itself like this:

public class MyClass: SomeClass
 {
    private let someVariable
    private var subdelegate :DelegateType?

    public override func viewDidLoad()
    {
        super.viewDidLoad()
        subdelegate = DelegateType(parent: self)
        someOtherObject.delegate = subdelegate
    }
}

Then implement the delegate methods in the DelegateType.

private class DelegateType : NSObject, HiddenProtocol 
{
    private weak var parent: MyClass?

    init(parent: MyClass)
     {
        super.init()
        self.parent = parent
    }

    // Implement delegate methods here by accessing the members 
    // of the parent through the 'parent' variable
}
Cihan Tek
  • 5,349
  • 3
  • 22
  • 29
  • 5
    Thanks for the answer and comments but the problem with making it public is, anyone can call these methods manually, Delegate methods are not meant to be called manually, what about this? – Kapil Choubisa Dec 08 '15 at 11:57
  • Delegate methods are meant to be called by objects other than the class that defines them. That's the whole point of using protocols, letting other classes know that it can respond to some specific set of methods. It's obviously true that not all clients need or should see this information, but it's not possible to differentiate between the ones that should and the rest when they are all public. – Cihan Tek Dec 08 '15 at 12:09
  • Why do they need to be `public`, shouldn't `internal` do it too? I don't understand the compiler here... – fabb May 04 '16 at 15:37