iOS:后台模式下未调用didDiscoverPeripheral函数

4
我正在开发一个BLE项目,当应用程序在前台时一切正常。它可以发现和连接外设,所有的回调方法都能完美工作。
但问题是,当应用程序处于后台模式(我按下了主页按钮),只有 centralManagerDidUpdateState 委托方法被调用。
- (void)centralManagerDidUpdateState:(CBCentralManager *)central{
    switch (central.state) {
        case CBCentralManagerStatePoweredOn:
          [self.cbCentralManager scanForPeripheralsWithServices:nil options:@{ CBCentralManagerScanOptionAllowDuplicatesKey : @YES }];
            break;
        default:
            break;
    }
}

我使用了 scanForPeripheralsWithServices:nil 选项,但是当应用程序在后台时,didDiscoverPeripheral 回调从未被调用。我已经编辑了我的plist文件,添加了“bluetooth-central”选项以支持后台的BLE中心角色。
有什么想法为什么当应用程序在后台时 didDiscoverPeripheral 方法没有被调用?

didConnectPeripheral方法会在连接操作时被调用,而不是在搜索周边设备时。您是否收到了didDiscoverPeripheral方法的回调?请注意,在后台模式下,重复选项将被忽略,您只会收到每个周边设备的单个发现事件。 - Paulw11
1
是的,问题在于 didDiscoverPeripheral 实际上没有被调用,我已经修改了我的问题。如果应用程序在前台已经开始扫描外设,当应用程序在后台时,scanForPeripheralsWithServices 回调会针对同一外设被调用吗?当 iOS 在前台找到这个外设时,它会忽略重复的情况吗? - ding
1
如果在前台或后台已经传递了给定外围设备的发现通知,则您将不会在后台收到任何进一步的发现通知。 - Paulw11
1
如果我想在后台仍然接收到相同外设的 didDiscoverPeripheral 回调,我该怎么做?我需要初始化一个新的 Central 类来重新开始扫描吗?实际上,我想在应用程序在后台时重新连接相同的外设。如果没有调用 didDiscoverPeripheral,我该如何重新连接?在苹果蓝牙指南中,我可以使用 retrievePeripheralsWithIdentifiers: 来恢复外设。但是我从 retrievePeripheralsWithIdentifiers: 方法中获取到了空的外设。 - ding
2
如果您想连接,只需发出连接请求。一旦外围设备重新进入范围,连接将完成,并且您将收到对didConnectPeripheral的调用。基本上,在didDisconnectPeripheral中,只需使用其外围对象调用connect即可。 - Paulw11
4个回答

3

3
我正在处理Estimote Nearable类型的信标。在iOS10 SDK更新后,我遇到了来自的异常,其中状态为:

<CBCentralManager: 0x17009e050>已提供恢复标识符,但委托未实现centralManager:willRestoreState:方法

为了解决这个问题,请在Xcode ->功能 ->背景模式中打开“背景模式”。

enter image description here


2

在后台扫描nil(scanForPeripheralsWithServices:nil)服务是不起作用的。您必须在后台搜索某些特定的服务。

您必须在scanForPeripheralsWithServices:方法中设置UUID,以便找到正在广告的外围设备/BLE设备。


1
从官方Apple参考资料中:
您可以在serviceUUIDs参数中提供表示服务UUID的CBUUID对象数组。这样做,中央管理器仅返回广告指定服务的外围设备(建议)。如果serviceUUIDs参数为nil,则返回所有已发现的外围设备,而不考虑其支持的服务(不建议)。如果中央管理器已经使用不同的参数进行扫描,则提供的参数将替换它们。当中央管理器对象发现外围设备时,它会调用其代理对象的centralManager:didDiscoverPeripheral:advertisementData:RSSI:方法。
已指定蓝牙中央后台模式的应用程序允许在后台扫描。也就是说,它们必须通过在serviceUUIDs参数中指定一个或多个服务来显式扫描。在后台扫描时,CBCentralManagerOptionShowPowerAlertKey扫描选项被忽略。
在此处:
已指定蓝牙中央后台模式的应用程序允许在后台扫描。也就是说,它们必须通过在serviceUUIDs参数中指定一个或多个服务来显式扫描。

因此,使用 nil 的 scanForPeripheralsWithServices:nil 在后台不起作用,您需要指定UUID列表。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接