简体   繁体   中英

Using Swift Protocol Inheritance

I am trying to create a delegate that uses traditional polymorphism to compensate for a device being bluetooth LE, bluetooth, etc and can't seem to get the syntax right for casting.

Here is my parent protocol and class:

@objc protocol DeviceDelegate
{
    func didConnectToDevice(name:String)
    func didFailToConnectToDevice(name:String)
    func didDisconnectFromDevice(name:String)

    func didWriteData(data:NSData)
    func didReceiveData(data:NSData)
}

class Device: NSObject
{
    var delegate: DeviceDelegate?
}

Now here is the child class and protocol simplified down:

protocol BluetoothDelegate : DeviceDelegate
{
    func didFindService(name:String)
    func didFindCharacteristic(name:String)
}

class BLE: Device
{
    func someFunc()
    {
        let bluetoothDelegate = (delegate as? BluetoothDelegate)
        bluetoothDelegate.didFindService(UUIDString)
    }
}

It throws the following error on the first line of that function:

Cannot downcast from 'DeviceDelegate?' to non-@objc protocol type 'BluetoothDelegate'

This doesn't make sense to me since it should allow casting to a child like a usual object does.

If I put @objc in front of BluetoothDelegate I get the following error:

@objc protocol 'BluetoothDelegate' cannot refine non-@objc protocol 'DeviceDelegate'

Anybody have any ideas on this?

When I copy your code and paste it directly into a playground and add @objc in front of your BluetoothDelegate definition, I get a message on this line:

bluetoothDelegate.didFindService("asdf")

'BluetoothDelegate?' does not have a member named 'didFindService'

Because you have used as? , there is a chance that bluetoothDelegate is nil . You should be using optional chaining here. Replacing with the following line reports no errors in the playground, indicating that you may have done something else in your code that you're not showing us.

bluetoothDelegate?.didFindService("asdf")

Alternatively, you could use this:

if let bluetoothDelegate = delegate as? BluetoothDelegate {
  bluetoothDelegate.didFindService(UUIDString)
}

The message you're seeing about DeviceDelegate not being an objc protocol indicates to me that you have written these in two different files and maybe forward-declared DeviceDelegate incorrectly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM