当前位置:  开发笔记 > IOS > 正文

BLE背景重新连接

如何解决《BLE背景重新连接》经验,为你挑选了1个好方法。

我想在设备被用户移出/终止后再重新连接到BLE设备,或者在后台模式下重新连接.

我知道这是可能的: - 用描述看这个问题

问题 - centralManager如果应用程序终止,我如何设置在后台模式下自动重新连接到外围设备?有人可以逐步描述如何完成它吗?

关于当前实施的几点说法:

我使用以下选项创建centralManager:

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本身而不是所需的服务.

另一个问题 - 重新连接外围设备是一个很好的选择,同时保持连接失去连接,如:

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

还尝试更改外围设备上的通知特性并在设备上读取它.如果所有这些都在前台完成 - 所有工作都很完美,但是如果连接在后台完成了一些时候didUpdateValueForCharacteristic根本没有被调用,但didUpdateNotificationStateForCharacteristic被调用没有错误 - 这意味着(我认为)我的身边做错了.也许你可以建议问题出在哪里

还有一个问题 - 将数据写入特征是否存在一些限制?因为在苹果样本中它被设置为20个字节.



1> Anton..:

首先,我想首先说我已经使用CoreBluetooth大约两年了,从我注意到CoreBluetooth 状态保存和恢复根本不可靠.你可以让它工作得那么"好",但你永远不会让它可靠地重新连接,除非Apple有一天修复它.

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

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

2)您将委托设置为nil in centralManager:willRestoreState:!因此,即使它确实连接,你也不会知道它:i

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

4)CBConnectPeripheralOptionNotifyOnConnectionKey使用蓝牙中央后台模式时没有必要,只是让用户讨厌,所以我不会用它.

5) ,,CBCentralManagerRestoredStatePeripheralsKey 是无效的初始化选项,以便您为什么使用这些我不明白..CBCentralManagerRestoredStateScanServicesKeyCBCentralManagerRestoredStateScanOptionsKey

5)如果蓝牙在应用程序终止时切换状态,则所有挂起的连接都将丢失,您将不会重新启动以了解它.这本身就意味着国家恢复是无用的.

无论如何,我很难过这么说,但如果你正在开发一个必须依赖外围设备在后台重新连接的应用程序,那么我不建议这样做.你会感到沮丧.我可能会写一篇关于Apple不想修复的Core Bluetooth中所有错误的文章.更可怕的是,你可以很容易地从一个应用程序破坏设备上全局的蓝牙连接,这样在设备重启之前没有应用程序可以使用蓝牙.这非常糟糕,因为它违反了苹果自己的沙盒原则.

如果您需要更多帮助,请告诉我们!

/一个


根本不可靠.你可以让它工作得那么"好",但你永远不会让它可靠地重新连接,除非Apple有一天修复它.
推荐阅读
殉情放开那只小兔子
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有