0

Using a Wi-Fi socket based adapter, I can successfully poll for a response like so:

    func writeMessageWithResponse(message: String) -> [String] {
        self.waitingForResponse = true
        let runLoop = NSRunLoop.currentRunLoop()
        if self.response != nil {
            self.response?.removeAll()
        }

        writeMessage(message) // this will set self.waitingForResponse to false when a response is received

        while self.waitingForResponse && runLoop.runMode(NSDefaultRunLoopMode, beforeDate: NSDate.distantFuture()) {
             // waiting for flag (self.waitingForResponse) to be set
        }

        return self.response!
    }

When I use this same code with a CBCentralManager BLE connection, the main thread is blocked and does not receive the response from the connection. I've tried changing the CBCentralManager to a different queue, but I get the same results.

Does anybody have an idea how to wait in a loop and still be able to receive a BLE response? I know a response is being sent, but the thread is blocked and not reading it.

Using an async function with a completionHandler won't work for this use case because I need a reusable function that can issue a chain of commands that each depend on the result of the last response.

Paulw11
  • 108,386
  • 14
  • 159
  • 186
iJeep
  • 989
  • 1
  • 10
  • 28
  • 1
    Polling is rarely a good idea; especially in a battery-powered user-centric mobile environment. You definitely need to look at some sort of command queue so that you can use the asynchronous response to trigger the next command. This could be something as simple as an array or more complicated like NSOperation objects – Paulw11 Mar 13 '16 at 23:00
  • Thank you. I am currently using a NSOperation, but I am now attempting to expand that to include completion handlers. – iJeep Mar 14 '16 at 23:02

1 Answers1

0

The CBCentralManager and CBPeripheral APIs are not really designed for this. You should be using the methods provided by CBPeripheralDelegate and CBCentralManagerDelegate protocols. Initialize your central manager with a dedicated queue so that you can listen for responses to your peripherals and act on that data as appropriate.

dbn
  • 458
  • 5
  • 12
  • Sorry I didn't make it clear. That function is in a class that extends CBPeripheralDelegate and CBCentralManagerDelegate. The problem was that the response was not being received while waiting in a loop, but would come through after the loop was abandoned. I'm now attempting to change the code to work asynchronously using completion handlers. – iJeep Mar 14 '16 at 22:57