2

Successfully connected my BLE device using corebluetooth library and set notify values for certain service from it on my ios app. Works fine in foreground and background modes.

I currently save the identifiers of the device to UserDefaults and need the ios device to be always connected to the device at all times.

Question: What are the best practices for corebluetooth implementation with the states of the ios app? Specifically:

  1. What should be implemented when user opens the app? (currently: I use the saved identifiers to reconnect to the ble device.. but is this necessary as corebluetooth should automatically stay connected to the device)
  2. What should be implemented when the user backgrounds the app?
  3. What should be implemented when the user reopens the app from background? (should i reconnect to the device?)
  4. What should be implemented when the user kills the app? Does the corebluetooth connection get disconnected?
  5. What should be implemented when battery is low and bluetooth is powered down or turned off by the device?

and lastly:

Is it necessary to implement the corebluetooth library in a singleton class to ensure that only one bluetooth manager is used by the app to connect to the devices?

the_legend_27
  • 571
  • 4
  • 11
  • As you have deleted your previous question, I would also suggest you another [thread](http://stackoverflow.com/questions/9896562/what-exactly-can-corebluetooth-applications-do-whilst-in-the-background) to read. This may helpful to you. – Hemang May 10 '17 at 03:59
  • thank you for your help hemang! went over the library for 2 days and finally found out the issue.. the problem was caused by where i assigned by cbcentralmanager in the appdelegate (https://forums.developer.apple.com/thread/53750) – the_legend_27 May 12 '17 at 05:03

1 Answers1

5

Here are some advises and best (as I can see them) practices. These are not craved in stone:

  1. When the user opens the app, it doesn't necessarily reconnects to the device. So your approach is good. However, you should check if the app wants to reconnect.
  2. When the user backgrounds the app and the device is connected, the device stays connected. So nothing to implement here unless some special cases. We will get to them later.
  3. When the user brings the app to the foreground (reopens it from background) and the device was connected before the app was sent to background, it still remains connected. So nothing to implement here.
  4. When user kills the app, the device is disconnected, and there's nothing you can do. You can try to reconnect to the device when the user opens the app again.
  5. I would monitor the device battery (check it once in a while) and when the battery reaches the critical level, let's say 5%, disconnect from the device.

And lastly: it is not necessary to implement it as a singleton. It is very convenient though when you have only one object that handles all the bluetooth connection. So, I'd say, singleton is a good choice.

In general you have to take into account two cases:

  1. The app is killed by the system (probably because of memory pressure or crash). When the app is killed while in background, the system will relaunch it and the func centralManager(_ central: CBCentralManager, willRestoreState dict: [String : Any]) function will be called. In this function you should try to reconnect to the bluetooth device. When the app is killed by the system while in foreground, sometimes (from my experience) the same function will be called. So you should do the same thing. When it's not called - see the following paragraph.
  2. The app is killed by the user. In this case you cannot relaunch the app. But when the user opens it again you should check the latest connection status, and try to reconnect to the device if needed. Since you save the connected device in UserDefaults (which is the right thing), you should have all the needed properties.

For any other cases - disconnections because the Bluetooth turns off (on the device or on the phone) or because the device is out of range, the system handles the reconnection. So basically, nothing to do here.

Once again, all this is not carved in stone. That's how I implemented it, and it works fine.

Max Pevsner
  • 4,098
  • 2
  • 18
  • 32
  • Nicely answer. I have doubts on these points: 2nd and 3rd? You said, a device should be connected even if an app goes to background or come to foreground from background. With me, it was disconnected after few seconds (or instantly). I was not sure about the reason thus implemented it a slight differently. I used to disconnect/reconnect for the background/foreground cases. This works nicely. Please add your thoughts. Thanks. – Hemang May 10 '17 at 04:06
  • "When user kills the app, the device is disconnected, and there's nothing you can do. You can try to reconnect to the device when the user opens the app again." <-- Not sure, but I think if the user does this but then turns the device off then on...they would be able to connect. – mfaani Jun 08 '17 at 14:48
  • I'm just saying that based on reading [here](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623013-application) "However, the system does not automatically launch your app if the user has force-quit it. In that situation, the user must relaunch your app or restart the device before the system attempts to launch your app automatically again.". I just thought notifications logic would apply – mfaani Jun 08 '17 at 15:05
  • If the user turns off his Bluetooth while the app is connected, and he turns it on after the os has suspended the app, will it launch the app? Anything special to do here? In my case app is not launched and when launched manually peripheral is stuck in connecting state. – Saleh Jan 05 '18 at 16:35