BLE背景重新连接

在用户或系统移出/终止设备后,我想重新连接到BLE设备/在后台模式下重新绑定。

我知道这是可能的: – 看到这个问题的描述

问题 – 如何设置centralManager自动重新连接到外设在后台模式,如果应用程序被终止? 有人可以一步一步描述如何做到这一点?

关于当前实施的几句话:

我使用以下选项创buildcentralManager:

 self.centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil options:@{ CBCentralManagerOptionRestoreIdentifierKey: @"myCentralManagerIdentifier", CBCentralManagerRestoredStatePeripheralsKey : @YES, CBCentralManagerRestoredStateScanServicesKey : @YES, CBCentralManagerRestoredStateScanOptionsKey : @YES }]; 

之后,我开始扫描BLE设备

 [self.centralManager scanForPeripheralsWithServices:[self discoverableCharacteristics] options:nil]; 

- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI我连接到外设:

  NSString *localName = [advertisementData objectForKey:CBAdvertisementDataLocalNameKey]; [self.centralManager stopScan]; peripheral.delegate = self; [self.centralManager connectPeripheral:peripheral options: @{ CBConnectPeripheralOptionNotifyOnNotificationKey : @YES }]; 

之后,我可以发现服务和特点 – 所有看起来像确定。 当我发现特性和读取/写入数据我cancelPeripheralConnection

在didDisconnect我重新连接到设备

 - (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(nullable NSError *)error { [central connectPeripheral:peripheral options:nil]; } 

我也实现了centralManager:willRestoreState:就像:

 NSArray *peripherals = dict[CBCentralManagerRestoredStatePeripheralsKey]; for (CBPeripheral *peripheral in peripherals) { [central connectPeripheral:peripheral options:nil]; peripheral.delegate = nil; } 

在plist。 添加所需的关键App communicates using CoreBluetooth

目前,如果我连接到设备并终止它 – 自动重新启动并连接到设备 – 一切正常,但如果它再次终止 – 什么都没有发生。

另外,如果我从外围移出,并回来 – 什么都没有发生。


更新

关于第5点 – 我的秋天 – 应该用connectPeripheral来使用这个键

WillRestoreState:

 NSArray *peripherals = dict[CBCentralManagerRestoredStatePeripheralsKey]; if (!peripherals.count) { peripherals = [central retrievePeripheralsWithIdentifiers:[self discoverableCharacteristics]]; } if (peripherals.count) { for (CBPeripheral *peripheral in peripherals) { [central connectPeripheral:peripheral options:@{ CBCentralManagerRestoredStatePeripheralsKey : @YES, CBCentralManagerRestoredStateScanServicesKey : @YES, CBCentralManagerRestoredStateScanOptionsKey : @YES }]; } } else { [self startScanning]; } 

目前的结果 – 应用程序将重新启动,如果它没有从托盘中刷出。 我使用我的Mac作为外设,所以有时候我不启动应用程序,使外设中心的作用可以连接到Mac本身而不是所需的服务。

另外一个问题 – 重新连接外围设备是否是一个好的select,而丢失连接可以保持连接,如:

 - (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(nullable NSError *)error { [central connectPeripheral:peripheral options:@{ CBCentralManagerRestoredStatePeripheralsKey : @YES, CBCentralManagerRestoredStateScanServicesKey : @YES, CBCentralManagerRestoredStateScanOptionsKey : @YES }]; } 

也尝试改变外设的通知特性并在设备上读取。 如果全部在前台完成 – 所有的工作都很完美,但是如果连接在后台完成,有时候didUpdateValueForCharacteristic没有调用didUpdateNotificationStateForCharacteristic ,但是没有错误地调用didUpdateNotificationStateForCharacteristic – 这意味着(我认为)在我身边做了错误的事情。 也许你可以build议哪里可以解决问题

还有一个问题 – 在将数据写入特性方面有一些限制吗? 因为在苹果示例中,它被设置为20个字节。

首先,我想先说我已经使用CoreBluetooth大约两年了,从我注意到,CoreBluetooth State Preservation和Restoration不能可靠地工作。 你可以得到它的工作“好”,但你永远不会得到它可靠地重新连接,除非苹果有一天修复它。

话虽如此,我想在你的设置上注意一些事情。

1)在centralManager:willRestoreState:你只能检索已经完成任何沟通,而应用程序被终止的外设。 这意味着你也应该实现centralManagerDidUpdateState:如果状态是CBCentralManagerStatePoweredOn那么你可以使用retrievePeripheralsWithIdentifiers:方法来检索其他外围设备并重置它们的委托。 这当然意味着你必须在你的应用程序某处存储外设标识符。 还记得在这里重置挂起的连接。

2)在centralManager:willRestoreState:设置为nil centralManager:willRestoreState: 所以,即使它连接,你也不会知道它我:P

3)如果应用程序被系统终止,您的应用程序将只会重新启动。 如果您从应用程序列表中手动刷卡,它将不会重新启动。 不幸的是,如果设备重新启动,它也不会重新启动。

4)当使用蓝牙中央背景模式时, CBConnectPeripheralOptionNotifyOnConnectionKey不是必需的,只是烦人的用户,所以我不会使用它。

5) CBCentralManagerRestoredStatePeripheralsKeyCBCentralManagerRestoredStateScanServicesKeyCBCentralManagerRestoredStateScanOptionsKey是无效的初始化选项,所以我不明白你为什么使用这些..

5)如果蓝牙切换状态,而应用程序被终止,那么所有挂起的连接将会丢失,你将不会重新启动了解它。 这本身就意味着国家恢复是无用的。

无论如何,我很难过这么说,但是如果你正在开发一个应用程序,必须依赖于在后台重新连接的外设,那么我不会推荐这样做。 你会感到沮丧。 我大概可以写一篇关于苹果公司不想解决的核心蓝牙问题的文章。 更可怕的是,你可以从一个单一的应用程序很容易地破坏设备上的全球蓝牙连接,以便没有应用程序可以使用蓝牙,直到设备重新启动。 这是非常糟糕的,因为它违背了苹果自己的沙箱原则。

如果您需要任何帮助,请告诉我!

/一个