Search code examples
swiftcore-bluetooth

How to pass potential error between methods


I'm trying to wrap Core Bluetooth Peripheral methods for use in React Native. It's a counterpart for already finished android code, so the API is set.

When I'm calling CBPeripheralManager.addService, I need to fulfill or reject a promise, handed from the javascript side.

The problem is, Core Bluetooth doesn't offer a callback for the method, it seems to expect private func peripheralManager(_ peripheral: CBPeripheralManager, didAddService service: CBService, error: Error?)

I'm new to iOS and Swift so this behavior seems strange to me. Any ideas how can I wrap the function so I can handle the error reporting properly?

Thanks

class BLE: NSObject, CBPeripheralManagerDelegate {
    var advertising: Bool = false
    var servicesMap = Dictionary<String, CBMutableService>()
    var manager: CBPeripheralManager!

    override init() {
        super.init()
        manager = CBPeripheralManager(delegate: self, queue: nil, options: nil)
    }

    func addService(promise, serviceUUID) {
        let serviceUUID = CBUUID(string: uuid)
        let service = CBMutableService(type: serviceUUID, primary: true)
        manager.add(service)
    }

    private func peripheralManager(_ peripheral: CBPeripheralManager, didAddService service: CBService, error: Error?) {
        if let error = error {
            // this should reject the addService promise
            return
        }
        // this should fulfill the promise
    }    
}

Solution

  • It's unclear what the type of promise is, but you'll need to store it somewhere, and then fulfill it later. For example, you might add a property:

    var pendingServices: [CBUUID: Promise] = [:]
    

    (I don't know what you're promise type really is here)

    Then you'd store it in addService:

    assert(pendingServices[serviceUUID] == nil)
    pendingServices[serviceUUID] = promise
    

    And later in (the correct; see my comment) delegate method, you'd deal with it:

    if let promise = pendingServices.removeValue(forKey: service.uuid) {
        promise.fulfill() // Or whatever you do with it
    }