我正在尝试在两个BLE设备之间交换数据。实际上客户端是功能正常的,而我的问题出在IOS手机的服务器端。
我创建了一个从NSObject和CBPeripheralManagerDelegate继承的BluetoothLEController。服务,广告,连接,订阅和didReceiveWrite
的所有部分均有效。
这是我的问题,当我同时两次或更多次调用CBPeripheralManager类的updateValue方法时,只有第一次调用成功。在Swift文档中,如果发送队列繁忙,则此函数返回false。 我编写了这样的伪无限循环
while !peripheralManager.updateValue(data,
for: messageContentCharacteristic,
onSubscribedCentrals: nil) {}
它可以工作,但实现起来确实很糟糕!
所以在那之后我尝试使用DispatchSemaphore
let semaphore = DispatchSemaphore(value: 1)
func write(_ data: Data) {
DispatchQueue.global().async {
self.semaphore.wait()
self.peripheralManager.updateValue(data,
for: self.messageContentCharacteristic,
onSubscribedCentrals: nil)
}
}
func peripheralManagerIsReady(toUpdateSubscribers peripheral: CBPeripheralManager) {
semaphore.signal()
}
所有线程正在运行。第一个电话updateValue
和我的客户收到通知。另一个正在等待。
但是,从未调用回调peripheralManagerIsReady#toUpdateSubscribers
并且我的应用程序被阻止了。
我正在尝试使用具有其他优先级的DispatchGroup和DispatchQueue进行其他方式,但是我的问题仍然相同。
我希望有人可以帮助我成为更好的开发者:)
答案 0 :(得分:0)
正如Paulw11所说,我实现了一个基于Swift算法俱乐部的通用队列。我坚决使用我的信号量,但仅出于线程安全。
let queue = Queue<Data>()
let semaphore = DispatchSemaphore(value: 1)
func write(_ data: Data) {
if !peripheralManager.updateValue(data,
for: messageContentCharacteristic,
onSubscribedCentrals: nil) {
semaphore.wait()
queue.enqueue(data)
semaphore.signal()
}
}
func peripheralManagerIsReady(toUpdateSubscribers peripheral: CBPeripheralManager) {
if !queue.isEmpty {
semaphore.wait()
if let data = queue.dequeue() {
peripheralManager.updateValue(data,
for: messageContentCharacteristic,
onSubscribedCentrals: nil)
}
semaphore.signal()
}
}