How long is a CBPeripheral's stored UUID valid for reconnection? [duplicate]

拥有回忆 提交于 2019-12-06 16:27:53

In my opinion, directly holding onto the CBPeripheral objects in an NSArray or NSDictionary is the easiest way. Connect and disconnect as many times as you would like (without scanning each time) to a CBPeripheral once it is retained. The only thing you have to be mindful of is the CBCentralManager's state. You will receive state changes by implementing the CBCentralManagerDelegate centralManagerDidUpdateState: method. If the state changes to anything except CBCentralManagerStatePoweredOn then you need to get rid of all of your retained CBPeripheral objects and do another scan once the state turns back on.

According to the apple docs:

If the state moves below CBCentralManagerStatePoweredOff, all CBPeripheral objects obtained from this central manager become invalid and must be retrieved or discovered again.

However, I would suggest invalidating/releasing all of your CBPeripheral objects if the state moves below CBCentralManagerStatePoweredOn. It is no secret that CoreBluetooth is a little buggy and this has seemed to help me avoid "invalid CBPeripheral" warnings in the past.

If you would like to identify a specific CBPeripheral after the app is reset or the device is shut down or even a network settings reset (cache reset) then you will need to have a custom implementation that uniquely identifies another device not based on anything CoreBluetooth offers you for free.

Here is how I do it in one of my apps:

  1. Alloc/Init a NSUUID object the first time the app is launched and save it in NSUserDefaults as a NSString. Think of this UUID as a pseudo-MAC address for your app. This UUID will remain constant for the lifetime of the app.
  2. centralManager discovers a CBPeripheral, connects, and then reads the value for a specific characteristic
  3. CBPeripheral device responds to the request with its non-bluetooth-related UUID from step 1. I also include a whole bunch of user provided information in this step along with the UUID.
  4. centralManager saves this UUID (and any other information you include) using Core Data or NSUserDefaults if it hasn't already.
  5. Repeat steps 2-4 for all newly discovered CBPeripherals.

Now, whenever centralManager discovers a CBPeripheral it can check its local database of UUIDs and determine which device is related to this CBPeripheral without a doubt.

See Paulw11's answer for how reconnect while in the background. Note that if your app has been quit by the user (swipe the app's preview up after pressing the home button twice), any long term "connects" will be cancelled even if the app is restarted.

It depends on the type of peripheral and the addressing scheme that it implements.

An iOS device operating as a peripheral using Core Bluetooth will change its address fairly frequently - in a matter of minutes.

For other peripheral devices, such as fitness monitors, HID devices etc, the address will never change (unless the peripheral manufacturer has also decided to introduce address randomisation) and it is "safe" to store the UUID string and attempt to scan and reconnection directly when the appropriate UUID is seen - note that you can't necessarily use the CBPeripheral, but you can store the UUID object from it.

You can also use background modes to automatically re-launch your app and connected to a peripheral. This scenario is described in the "lock" example of the Core Bluetooth programming guide. An app can issue a "connect" to a peripheral and it won't timeout.

In summary, you can't really store UUIDs for iOS based peripherals but for other peripheral types you 'probably' can.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!