Post

Replies

Boosts

Views

Activity

Reply to CBPeripheral gets stuck in connecting/disconnecting states
I believe I have figured out the root cause. Starting in iOS 17, if you have state restoration enabled, CoreBluetooth can return a new instance of CBPeripheral with the same identifier! As recommended by the docs we hold a strong reference to the CBPeripheral so that we can connect to it as needed. Also, per the docs, we have code implemented that checks identifier to see if that object needs updated. But we don't check that it's a new instance (ie memory address). This is from the debugger on a single breakpoint in centralManager(_:didDiscover:advertisementData:rssi:): (lldb) po peripheral <CBPeripheral: 0x280aac8f0, identifier = BC077734-EAE6-5F1C-446C-B56305A18176, name = D2493B7P, mtu = 0, state = disconnected> (lldb) po getPeripheral(peripheral).peripheral <CBPeripheral: 0x280ab11e0, identifier = BC077734-EAE6-5F1C-446C-B56305A18176, name = D2493B7P, mtu = 23, state = connecting> Notice how the identifiers match, but the memory address (and state) are different. The getPeripheral() function retrieves a previously retained peripheral as a wrapper object that holds a strong reference to the CBPeripheral, as well as some metadata specific to our app. I have verified that the CBCentralManager has not changed, and state restoration did not occur. This seems like a bug in iOS 17. I would expect the identifier to change if there is a new object. Otherwise, why have an identifier? I will file a report with Apple.
Dec ’23