未调用 BLE 外设委托
Posted
技术标签:
【中文标题】未调用 BLE 外设委托【英文标题】:BLE Peripheral delegate not called 【发布时间】:2017-11-17 01:18:06 【问题描述】:我最近从 Swift 3 升级到了 Swift 4,从 ios 10.3.3 升级到了 iOS 11.1。
我正在开发一个使用 BLE 进行双向通信的应用程序。工作流程如下:
-
外围设备 - 广告身份
CENTRAL - 接收身份(处理它...)
CENTRAL - 响应外围设备
外围设备 - 从中央接收响应
完成
我的代码在更新之前运行良好,但现在不行了。在第 4 步结束时,我执行以下行:
peripheral.writeValue(encryptedData!, for: characteristic, type: .withResponse)
这应该调用以下委托方法,但它没有:
public func peripheral(_ peripheral: CBPeripheral, didWriteValueFor descriptor: CBDescriptor, error: Error?)
print("Did Write")
print("Error=\(error?.localizedDescription)")
它还应该(并且正在调用)外围设备上的以下委托方法,但它没有:
public func peripheralManager(_ peripheral: CBPeripheralManager, didReceiveWrite requests: [CBATTRequest])
print("did receive write request")
服务和特性设置如下:
let prefs = Preferences()
let strServiceUUID = prefs.GetString(key: Preferences.PREF_IDENTITY_SERVICE_UUID, defaultVal: "")!
let strCharacteristicUUID = prefs.GetString(key: Preferences.PREF_IDENTITY_CHARACTERISTIC_UUID, defaultVal: "")!
print("ServiceUUID=\(strServiceUUID)")
print("CharacteristicUUID=\(strCharacteristicUUID)")
mServiceUUID = CBUUID(string: strServiceUUID)
mCharacterUUID = CBUUID(string: strCharacteristicUUID)
mCBBluetoothServices = CBMutableService(type: mServiceUUID, primary: true)
//lets configure the data we want to advertise for
var characteristics : [CBCharacteristic] = []
//let strData : String = "933911"
//let data = strData.data(using: .utf8)
let cbProperties: CBCharacteristicProperties = [.read, .write, .notify]
let cbPermissions: CBAttributePermissions = [.readable, .writeable]
mIdentityObjectCharacteristic = CBMutableCharacteristic(type: mCharacterUUID,
properties: cbProperties,
value: nil,
permissions: cbPermissions)
characteristics.append(mIdentityObjectCharacteristic)
mCBBluetoothServices.characteristics = characteristics
mCBPeripheralManager.add(mCBBluetoothServices)
【问题讨论】:
【参考方案1】:我不确定为什么升级 OS 和 Swift 版本会破坏您的代码,但是在我看来您可能使用了错误的委托方法?
试试这个
func peripheral(CBPeripheral, didWriteValueFor: CBCharacteristic, error: Error?)
而不是这个
func peripheral(CBPeripheral, didWriteValueFor: CBDescriptor, error: Error?)
【讨论】:
我把它改成了正确的委托方法,但是当我调用 peripheral.writeValue(encryptedData!, for: characteristic, type: .withResponse) 时它仍然没有陷入陷阱。 这很不幸。您是否确保您确实已连接、拥有所有权限、启用了 BLE 等?我自己升级到 iOS 后遇到了一些 BLE 连接问题,特别是对于 iPhone 5s 等旧手机。如果您发布更多代码,我可以进行比较,看看我们是否看到了相同的问题。【参考方案2】:斯威夫特 4
对于任何类型的更新特性(例如读/写特性),将调用 didUpdateValueFor
委托。
所以,首先检查以下委托方法。
func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?)
print("didUpdateValueForChar", characteristic)
if let error1 = error
alertMSG(titleString: "Error", subTitleString: "Found error while read characteristic data, Plase try again", buttonTitle: "OK")
print(error1)
else
print("Update Characteristic: ", characteristic)
func peripheral(_ peripheral: CBPeripheral, didWriteValueFor characteristic: CBCharacteristic, error: Error?)
print("Write Characteristic :", characteristic)
【讨论】:
【参考方案3】:斯威夫特 5 iOS 13
需要检查的一些事项:
-
确保将外设的
delegate
设置为符合CBPeripheralDelegate
协议的任何控制器(这也应该是需要实现peripheral(_:didWriteValueFor:error:)
方法的同一控制器)。
确保您没有指定 .withoutResponse
写入类型。
正如this other answer 所提到的,有两个非常相似的委托方法具有签名peripheral(_:didWriteValueFor:error:)
。确保你正在实施正确的。
写入特征时:
writeValue(_:for:type:)
:
func writeValue(_ data: Data,
for characteristic: CBCharacteristic,
type: CBCharacteristicWriteType)
peripheral(_:didWriteValueFor:error:)
func peripheral(_ peripheral: CBPeripheral,
didWriteValueFor characteristic: CBCharacteristic,
error: Error?)
写入描述符时:
writeValue(_:for:)
func writeValue(_ data: Data,
for descriptor: CBDescriptor)
peripheral(_:didWriteValueFor:error:)
func peripheral(_ peripheral: CBPeripheral,
didWriteValueFor descriptor: CBDescriptor,
error: Error?)
容易混淆2组write和delegate方法。
由于您正在使用:
peripheral.writeValue(encryptedData!, for: characteristic, type: .withResponse)
write 和 delegate 对的代码应该是这样的:
class BluetoothController: CBCentralManagerDelegate, CBPeripheralDelegate
...
func writeSomething(to characteristic: CBCharacteristic, of peripheral: CBPeripheral)
let something = "1234"
NSLog("Writing \(something) to \(characteristic.uuid.uuidString)")
peripheral.delegate = self // <===== You may have forgotten this?
peripheral.writeValue(something.data(using: .utf8)!,
for: characteristic,
type: .withResponse)
...
func peripheral(_ peripheral: CBPeripheral, didWriteValueFor characteristic: CBCharacteristic, error: Error?)
if error != nil
NSLog("Write error: \(String(describing: error))")
else
NSLog("Wrote value to \(characteristic.uuid.uuidString)")
【讨论】:
以上是关于未调用 BLE 外设委托的主要内容,如果未能解决你的问题,请参考以下文章
Android外设BluetoothGattServerCallback onServiceAdded()没有被调用
未调用 Android BLE onCharacteristicChanged
未调用 Android BLE onCharacteristicChanged()
iOS iPad 应用程序:未调用具有两个 UIScrollViews 和一个 UIPageControl 的 ViewController 的委托(未调用分页的委托函数)