SwiftUI / BlueJay 意外外设错误

SwiftUI / BlueJay unexpectedPeripheral Error

此 post 与我从蓝牙 API BlueJay 收到的错误有关。 我有这个错误,我无法找到文档。

"CBCentralManager initialized."
"Bluejay with UUID: 6A7273D6-66D7-4C36-B6A4-E59DC84422F7 started."
2021-07-19 13:24:33.079775-0400 Argon18 UAT[9780:4330125] [connection] nw_endpoint_handler_set_adaptive_read_handler [C1.1 172.217.13.170:443 ready channel-flow (satisfied (Path is satisfied), viable, interface: en0, ipv4, dns)] unregister notification for read_timeout failed
2021-07-19 13:24:33.080006-0400 Argon18 UAT[9780:4330125] [connection] nw_endpoint_handler_set_adaptive_write_handler [C1.1 172.217.13.170:443 ready channel-flow (satisfied (Path is satisfied), viable, interface: en0, ipv4, dns)] unregister notification for write_timeout failed
"Error: unexpectedPeripheral(Bluejay.PeripheralIdentifier(uuid: 0BC9C8FE-74FB-A237-D61B-F28748FE7EC5, name: \"ARGON04280CEC\"))"
"Central manager state updated: Powered On"

我在应用程序启动后收到此消息,它在显示主视图时所做的第一件事是尝试连接到默认 BLE 设备。

为此,我从 DB 中获取它的实体,然后使用商店外设 ID 和外设名称创建一个 PeripheralIdentifier 结构,然后传递给 BluJay API。

根据上面的错误,这失败了,因此我设置了一个按钮来手动重试此代码,这确实有效。

我感觉 BlueJay 需要很长时间才能完成设置,而且我在启动 BueJay 后发送请求的速度太快了。

这是设置 BluJay 的代码

self.bluejay.register(logObserver: self)
bluejay.registerDisconnectHandler(handler: self)
bluejay.register(connectionObserver: self)
bluejay.register(serviceObserver: self)
self.bluejay.start()

此代码设置在 Singleton 对象中,该对象在调用连接之前被调用。 (我确实测试过在应用程序启动时调用初始化程序,但我遇到了同样的问题)

这是用来获取存储在数据库中的 BLE 设备信息的代码。

.onAppear(perform: {
            let bleManager = A18BLEManager.shared
            if bleManager.model == nil {
                if let bike = A18DataStore.shared.getDefautBike(){
                    bleManager.connect(bikeID: bike.bleID!, name: bike.peripheralName!)
                }
            }
        })

func getDefautBike() -> Bike?
    {
        var bike: Bike? //Bike is a NSManagedObject
        let fetchRequest = Bike.fetchRequest() as NSFetchRequest<Bike>
        
        if let idString = UserDefaults.standard.object(forKey: "defaultBikeUUID") as? String, let bleID = NSUUID(uuidString: idString)
        {
            fetchRequest.predicate = NSPredicate(format:"%K == %@", #keyPath(Bike.bleID), bleID)
        }
                
        do{
            bike = try viewContext.fetch(fetchRequest).first
        }
        catch let error {
            debugPrint("Fetch Error: \(error)")
        }
        return bike //does return a valid record with valid UUID and name
        
    }

func connect(bikeID id: UUID, name: String) {
        self.connect(PeripheralIdentifier(uuid: id, name: name))
    }

func connect(_ peripheral: PeripheralIdentifier) {
    self.bluejay.connect(peripheral, timeout: .seconds(15)) { [unowned self] connectionResult in
        switch connectionResult {
        case .success:
            readBikeInfo()
            debugPrint("Connection attempt to: \(peripheral.description) is successful")
        case .failure(let error):
            debugPrint("Error: \(error)")
        }
    }
}

函数 getDefautBike() 执行 return 一个对象并且信息有效。

为了对此进行测试,我在调用此应用的不同位置设置了一个按钮。

A18BLEManager.shared.connect(bikeID: UUID(uuidString: "0BC9C8FE-74FB-A237-D61B-F28748FE7EC5")!, name: "ARGON04280CEC")

并且此调用将有效,它仅在另一个视图中有效,如果我在主视图中的主调用站点上使用它,则会出现相同的错误。

编辑:好的,写完之后。我试图在主视图显示 5 秒后设置呼叫。事实上,这些联系是有效的。所以最后真正的问题是 BlueJay 需要多长时间来设置?

没有具体的蓝牙可用时间。 OS 将通过在委托上调用 centralManagerDidUpdateState() 来告诉您。 Bluejay 通过它的 ConnectionObserver 暴露了这一点,它将在准备就绪时用 true 调用 bluetoothAvailable() 。您需要注意这一点以确定蓝牙何时可用。实际上,这通常在几百毫秒内,但如果天线已经通电,它可能比这快得多(接近但不完全是瞬时的)。

在您的日志中,您将此转换视为“中央管理器状态已更新:已启动”。我强烈希望您在看到之前尝试访问蓝牙堆栈。