微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

SwiftUI / BlueJay 意外外围错误

如何解决SwiftUI / BlueJay 意外外围错误

这篇文章是关于我从蓝牙 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),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 对象中,该对象在调用连接之前被调用。 (我确实测试过在应用程序启动时调用初始化程序,但我遇到了同样的问题)

这是为了获取存储在 DB 中的 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() 确实返回一个对象,并且信息是有效的。

为了测试这个,我在应用程序的不同位置设置了一个按钮来调用它。

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

这个调用会起作用,它只在另一个视图中起作用,如果我在主视图的主调用站点上使用它,这将得到同样的错误

编辑:好的,写完之后。我尝试在显示主视图 5 秒后设置呼叫。并且确实连接有效。所以最终真正的问题是 BlueJay 需要多长时间来设置?

解决方法

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

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。