I'm working with a Bluetooth peripheral that after connecting to it there is a ACK back and forth before it actually can send me the data that I need.
The flow is like this:
I have implemented the needed logic in the protocol method for State Preservation and Restoration centralManager(_ central: CBCentralManager, willRestoreState dict: [String : Any])
Question 1:
When the app is in the background and iOS decides to take over the Bluetooth communication (for resource reasons), how will iOS manage to do steps 5, 6 and 7?
Because if it can't then the peripheral won't be able to send the data that the app needs in step 7.
Question 2:
In the docs I read that iOS might start your app for a few seconds. Will the viewDidLoad
method of my root ViewController be executed in that case? That's where I instantiate the CBCentralManager
Some of the many online resources that I've found:
These two comments from Paulw11 helped me understand what was going on:
No, that doesn’t happen. If you have a pending discovery, a pending “connect” or you have an active notify on a characteristic then iOS will relaunch your app so that it can handle the discovery, the connection or the notification. iOS can’t do this on your behalf; it doesn’t know what you want to do. – Paulw11
Having your Bluetooth object attached to a view controller is a bad idea if you want to perform operations in the background. I suggest a singleton or an object owned by your app delegate – Paulw11
First, I was under the wrong assumption that iOS will try to handle all bluetooth communication on behalf of my app when my app was in the background and iOS had to kill it. The reality is that iOS starts the app in background mode for a limited period of time so that you can run your restoration code.
Finally, having the logic in the viewDidLoad
of my ViewController was wrong. I have created a BluetoothManager
class and I instantiated it in the application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool
method of my AppDelegate