bluetooth-lowenergy - 当应用程序被系统杀死时不会调用 WillRestoreState

标签 bluetooth-lowenergy core-bluetooth cbcentralmanager ios-bluetooth state-restoration

我正在尝试创建一个连接到血压袖带的应用程序。我想在应用程序中启用状态恢复,这样即使应用程序被系统终止,当血压袖带可用并正在传输时,仍然可以调用应用程序。以下是我迄今为止尝试过的一些事情。

1)在centralManager init中添加资源标识符并为其分配后台串行队列

var ble_dispatchQueue = DispatchQueue(label: "com.xyz.ios.ble")
        let opts = [CBCentralManagerOptionShowPowerAlertKey : true,    CBCentralManagerOptionRestoreIdentifierKey:
            "ios.xyz.ble.peripheral.identifier"] as [String : Any]

        self.centralManager = CBCentralManager(delegate : self, queue : ble_dispatchQueue, options : opts)

2) 实现 willRestoreState 和centralManagerDidUpdateState

   func centralManager(_ central: CBCentralManager, willRestoreState dict: [String : Any]) {

    print("will restore state called")
    if let peripheralsObject = dict[CBCentralManagerRestoredStatePeripheralsKey] {
        // 2
        let peripherals = peripheralsObject as! Array<CBPeripheral>
        // 3
        if peripherals.count > 0 {
            // 4
            self.peripheralDevice = peripherals[0]
            // 5
            self.peripheralDevice?.delegate = self
        }
    }
}

centralManagerDidUpdateState:

func centralManagerDidUpdateState(_ central: CBCentralManager) {

    if central.state != .poweredOn {
        self.peripheralDevice = nil
        return
    }
    startScan()

    // 1

    guard let peripheral = self.peripheralDevice else {
        return
    }
    // 2
    guard peripheral.state == .connected else {
        return
    }
    // 3
    guard let peripheralServices = peripheral.services else {
        return
    }
    // 4
    serviceUUID = deviceParameters.deviceTypeUUIDs![0]

    if let serviceIndex = peripheralServices.index(where: {$0.uuid == serviceUUID}) {
        let ANDService = peripheralServices[serviceIndex]
        let characteristicUUIDs = deviceParameters.deviceCharacteristicUUIDs
        if let cUUIDs = characteristicUUIDs, let characteristics = ANDService.characteristics {
            // 6
            for i in 0..<cUUIDs.count {
                if let characteristicIndex = characteristics.index(where : {$0.uuid == cUUIDs[i]}) {
                    let characteristic = characteristics[characteristicIndex]
                    // 7
                    if !characteristic.isNotifying {
                        peripheral.setNotifyValue(true, for: characteristic)
                    } else {
                        peripheral.readValue(for: characteristic)
                    }
                } else {
                    // 8
                    peripheral.discoverCharacteristics(characteristicUUIDs, for: ANDService)
                }
            }
        }
    } else {
        // 5
        peripheral.discoverServices([serviceUUID])
    }

}

我尝试测试它的方法是调用:-

kill(getpid(), SIGKILL);

模拟系统杀死进程。我不会摆弄蓝牙状态/飞行模式或手机重启。 我在 didLaunchWithOptions 中初始化我的centralManager 我在 didLaunchWithOptions 处设置了断点,每次 BP 袖带准备好连接时都会调用该断点,而在 willRestoreState 处设置断点,该断点永远不会被调用。

有人可以建议我还能做什么来调用 willRestoreState 吗?

最佳答案

您需要向 CBCentralManager 添加恢复 ID,否则永远不会调用委托(delegate)方法。

let options = [CBCentralManagerOptionRestoreIdentifierKey: "my-central"]
self.centralManager = CBCentralManager(delegate: self, queue: nil, options: options)

完成后,实例化 CBCentralManager 时始终会调用 willRestoreState

此外,请确保您的 Info.plist 中具有包含“bluetooth-central”项目的 UIBackgroundModes(数组)。

关于bluetooth-lowenergy - 当应用程序被系统杀死时不会调用 WillRestoreState,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49948667/

相关文章:

Android BLE 在绑定(bind)后断开连接

iOS Corebluetooth 广告和扫描,同时应用程序在后台

swift - CBCentralManagerDelegate didRetrievePeripherals 未找到

swift - CBCentralManager 停止扫描需要多长时间?

ios - 如何准确地将 NSData 转换为 struct

ios - 从 CBCentralManagerDelegate 回调以在 IOS8 上检索 CBPeripheral

android - 让 Samsung Android 设备作为 iBeacon 做广告

swift - CBCentralManager State 最初注册为 .unknown

ios - CoreBluetooth 检测外设

ios - CBPeripheral 连接在调用 discoverServices 后保持断开连接