Search code examples
iosswiftbluetoothcore-bluetooth

Connect to bluetooth CBPeripheral after app restart


I have a bluetooth device. Once I am connected with it, I want to reconnect to it in the background. The problem is that I do not know how I can reconnect to the device after the user force quitted the app (even after new app start)

What I have: A bluetooth device with no services in advertisement data.

Because it has no advertisement data I can't search for peripherals with services in background. So for background excecution I need to call centralManager.connect()

If the app shuts down because of a memory issue or something similar, I can restore everything in centralManagers delegation method willRestoreState The dict contains the peripheral that I can obtain with the CBCentralManagerRestoredStatePeripheralsKey. (As well I implemented to get the UIApplicationLaunchOptionsKey.bluetoothCentrals from launchOptions in willFinishLaunchingWithOptions

The problem

The restoration just works if the user is not force quitting the app. So I know that I can't relaunch the app myself with code again.

All I want is that if the user restarts the app to restore my CBPeripheral. After I could call centralManager.connect(peripheral) again.

additional Info

I store the uuid of the peripheral (peripheral.identifier.uuidString) in NSUserDefault Data.

Ideas

  • I thought about creating a CBPeripheral object with device infos. If I read everything correct it is not possible.
  • If I save the CBPeripheral in Core Data I do not know what will happen if Apple changes CBPeripherals API, probably it would be a bad idea.
  • On some way apple is able to take a snapshot of the CBPeripheral. Can I trigger this snapshot so that I can restore the peripheral with UIApplicationLaunchOptionsKey.bluetoothCentrals and CBCentralManagerRestoredStatePeripheralsKey every time?

Solution

  • The CBPeripheral object that you connected to in the first place will have an identifier property. You should store this identifier to disk so that you can load it again once the app is launched at a later time. Then, after you have created a new instance of CBCentralManager, you call the retrievePeripheralsWithIdentifiers: method of the manager (with the identifier you loaded earlier) to fetch the CBPeripheral object again. At this point you can connect the peripheral like you did earlier.