Search code examples
iosswiftcore-bluetoothcbcentralmanager

init CBCentralManager: Type of expression is ambiguous without more context


Trying to initialize a CBCentralManager in a Swift 4.2 project. Get the error shown in comment:

import CoreBluetooth

class SomeClass: NSObject, CBCentralManagerDelegate {

    // Type of expression is ambiguous without more context
    let manager: CBCentralManager = CBCentralManager(delegate: self, queue: nil)

    // MARK: - Functions: CBCentralManagerDelegate

    func centralManagerDidUpdateState(_ central: CBCentralManager) { }
}

If I switch self out for nil the error goes away, so I think I'm missing something important from my conformance to CBCentralManagerDelegate...

Can I use the manager without a delegate; and if not, what do I need to do to resolve the error?


Solution

  • The diagnostic here is misleading. The problem is you can't refer to self in the place you are (self there would be the class, not the instance).

    There are a few ways to solve this, but a common way is a lazy property:

    lazy var manager: CBCentralManager = {
        return CBCentralManager(delegate: self, queue: nil)
    }()
    

    The other approach is a ! variable:

    var manager: CBCentralManager!
    
    override init() {
        super.init()
        manager = CBCentralManager(delegate: self, queue: nil)
    }
    

    Both are somewhat ugly, but they're about the best we can do in Swift currently.

    Remember that the lazy approach won't create the CBCentralManager at all until the first time it's referenced, so it's a bit more common to use the ! version for this particular case.