bluejay
bluejay copied to clipboard
Allow users to find out which peripheral is being connected to
Summary:
In our app, we can pair/bond with multiple peripherals, and display each of them independently within the app. As part of that display, we want to show the connected status of the peripheral as one of the following:
- Disconnected - We aren't connected to the peripheral.
- Connecting - We aren't connected to the peripheral, but iOS is actively trying to connect to the peripheral (for example, you were connected to the peripheral, and then walked out of range, and the connection was lost).
- Connected - We are connected to the peripheral.
Disconnected & Connected are easy, and we can just use the ConnectionObserver.connected and ConnectionObserver.disconnected callbacks to determine when a peripheral connects and disconnects.
Telling if a peripheral is being connected to has been really difficult. I had 2 ideas that I played with, but ran into problems with:
- CBPeripheral.state supports KVO, and seems to give an accurate description of if a peripheral is being connected to (e.g. If you are connected to a peripheral, then become disconnected because you are out of range, but iOS is still trying to connect to it, the peripheral's state properly will be isConnecting).
This property is not accessible through bluejay, because bluejay doesn't give access to the cbCentralManager, so this isn't really an option. Also, the actual CBPeripheral instance is never given to us from bluejay, so we can't access the state property that way.
- We could use the DisconnectHandlers autoReconnect flag to know if we should consider ourselves to be actively connecting to the peripheral or not.
The biggest problem I see with this is on startup, it's possible that iOS does state restoration, and iOS is then actively trying to connect to a peripheral, but I don't see how we would get updated with that information.
Sorry if this wasn't the right place to ask this question, I wasn't sure where to ask.
Ah, interesting. This sounds like a new feature we could add to Bluejay, but yes, as you've found out we don't support this yet. Your quickest solution might be to fork Bluejay and implement that yourself.
We definitely don't want to be exposing the manager nor peripheral from CB, because as soon as you get one or the other, you can issue BLE operations directly outside the context of Bluejay's queueing system - and at that point Bluejay basically ceases to be anything meaningful nor useful.
To support this, we might need to add new observer types or events, and notifications in the following places:
- public func centralManager(_ central: CBCentralManager, willRestoreState dict: [String: Any])
- for notifying during state restoration
- func willConnect(to peripheral: CBPeripheral)
- for notifying any connection requests going through the queue