App does not wake up in the background when using AccessorySetupKit and Bluetooth background modes

I'm building a bluetooth device that is connected to my app. The device I'm building will be connected to the phone as much as possible, and when the user leaves the device's range and then comes back later, I expect the OS to wake the app up when it reconnects in the background using the CoreBluetooth willRestoreState wake up method. Using just CoreBluetooth for pairing, I've confirmed that the phone will reconnect to the device while in the background and the app gets woken up when that happens.

I'm hoping to use ASK for pairing instead as it's a much nicer user experience. When I initiate and confirm pairing via ASK, I can see that it's connected and paired successfully and I see my device and app connected as I expect. But when the device goes away, and the app has been in the background, and then I come in range of the phone, the device never reconnects automatically in Bluetooth settings. When I manually tap the device in settings to connect, it does connect, but I don't think my app gets woken up and restored as I don't see the requests I expect happening when it's in the background.

Does ASK support scanning for peripherals via CoreBluetooth while in the background, or automatic reconnection? I assumed that when my app is launched, I activate the ASAccessorySession session, and the .activated callback will fire, but I'm not seeing that happen.

Answered by DTS Engineer in 818327022

I'm hoping to use ASK for pairing instead as it's a much nicer user experience. When I initiate and confirm pairing via ASK, I can see that it's connected and paired successfully and I see my device and app connected as I expect.

You're actually moving in the right direction here but you've misunderstood the relationship between ASK and CoreBluetooth. ASK's role here is to establish the relationship between a particular accessory and your app. However, once that relationship is established, CoreBluetooth's background operation should work exactly the same it does without ASK.

That's also why the answer here:

Does ASK support scanning for peripherals via CoreBluetooth while in the background, or automatic reconnection?

...is no. The point of ASK is to get the users approval of the relationship between your app and accessory. By defintion, that has to happen in the foreground.

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

Accepted Answer

I'm hoping to use ASK for pairing instead as it's a much nicer user experience. When I initiate and confirm pairing via ASK, I can see that it's connected and paired successfully and I see my device and app connected as I expect.

You're actually moving in the right direction here but you've misunderstood the relationship between ASK and CoreBluetooth. ASK's role here is to establish the relationship between a particular accessory and your app. However, once that relationship is established, CoreBluetooth's background operation should work exactly the same it does without ASK.

That's also why the answer here:

Does ASK support scanning for peripherals via CoreBluetooth while in the background, or automatic reconnection?

...is no. The point of ASK is to get the users approval of the relationship between your app and accessory. By defintion, that has to happen in the foreground.

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

Does that mean that after the user pairs the two and we establish the connection with CoreBluetooth and include CBConnectPeripheralOptionEnableAutoReconnect and the user walks in range of the peripheral, it should launch the app with .bluetoothCentrals launch key, and automatically reconnect without any need to scan? I've made sure to activate the ASAccessorySession when the app loads.

In my testing, what I do is launch the app via Xcode, put my device in a faraday bag and verify that it's disconnected, hit the Stop button in Xcode, and then take the device out of the faraday bag. I notice that sometimes the device does reconnect while the app is in the background (i verified this by pinging my server when the app is launched with .bluetoothCentrals key). But when I put the device back in the faraday bag, wait sometime, and then take it out again, I don't see the expected pings (I ping my server when the device reconnects as well). This seems to only happens when paired via ASK.

I'm wondering if this has to do with the ASAccessorySession session somehow stopping working at some point in the background? Could the session be getting invalidated some how? Is there a way to detect that, and what should I do if it does that while my app is suspended or backgrounded?

I had a bit of a revelation - I noticed my phone battery was around 21% when it wasn't connecting in the background. I plugged in my phone and repeated my tests by placing the device I'm working with in/out of the faraday bag, and I verified that the .bluetoothCentrals key would wake up my app, so I'm guessing iOS doesn't try to reconnect to peripherals in the background when the battery is low - is there a specific percentage this happens at? I would have expected 20% since that's when you get the 'Low Battery' alert, but i was definitely >20%.

Thanks so much @DTS Engineer Kevin! You all are truly the underappreciated superheroes in the apple development ecosystem (the number of threads Quinn answers must be around 1% of the content of the internet itself), and I appreciate the care and thought you all put to your responses on these support threads.

App does not wake up in the background when using AccessorySetupKit and Bluetooth background modes
 
 
Q