Hello,
We currently experience issues with bluetooth reconnects. We had this issue since iOS 9, but it got way worse with iOS 10.
We have developed a BTLE Device which is intended to track a users car drives. We want our App to reconnect to the device as soon as it comes into range (again).
Short overview of what the btle part of the app does:
- Scan and bond with device
- Saves device identifier
- Talks with device until out of range
- // Everything works great until here
- Call BtCentralManager.connect() for device (retrieved via btCentralManager.retrievePeripherals)
- Wait for didConnect or didFailToConnect to proceed.
Everythings works great, but sometimes (1/5) a BTCentralManager.connect() does seem to timeout. We then never get a onDeviceConnect and the only chance to reconnect to our btle device is to restart the app (so it's not a hardware issue, also works perfect with android)
We do:
- Keep a strong reference to all peripherals we requested a connect
- Set the delegate of all peripherals to our singleton bluetooth manager
- Use our own queue on the central manager
- Have only one CBCentralObject app-wide
- Only connect with one device per time
- It makes no difference if the app is in background or foreground
- The first connect always works, but then it is total random when a following requests "dies"
- CentralManager delegate set correctly
- Our hardware does NOT use random addresses for itself
- Our hardware can handle ios random addresses
Most times it even connects when the connection request is multiple days old (over the weekend or so) and the app is in background.
Is there anything we can do to make this more stable? It's extremly frustrating for our customers to close the app everytime we are in this faulty state.
Here are the relevant part of our code if that helps:
// Reconnecting
devicesToConnect = btCentralManager.retrievePeripherals(withIdentifiers: deviceUUIDs)
// We always get the correct devices
for device in devicesToConnect {
if device.state == .disconnected {
device.delegate = self
btCentralManager.connect(device, options: nil)
} else {
// Log device state
// When this happens the device(s) are always in ".connecting" state
}
}
Regards, Mike