ios – 订阅来自CBC特性的通知不起作用

前端之家收集整理的这篇文章主要介绍了ios – 订阅来自CBC特性的通知不起作用前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
首先要做的事:运行OSX 10.10.4,iOS 4,Xcode 6.3.2,iPhone 6,Swift

短篇小说:我在这里有一个蓝牙LE设备,我希望在特征值发生变化时收到通知,例如:通过用户输入.尝试订阅它不会成功,而是产生错误错误域= CBATTErrorDomain代码= 10“找不到该属性.”

长话:所以,我有一个BluetoothManager类,在我的$CBCentralManager.state是.PoweredOn时,我开始扫描Peripherals.这很容易,我甚至是一个好公民,专门为有我想要的服务的人扫描

centralManager.scanForPeripheralsWithServices([ServiceUUID],options: nil)

希望这会成功,我实现了以下委托方法

func centralManager(central: CBCentralManager!,didDiscoverPeripheral peripheral: CBPeripheral!,advertisementData: [NSObject : AnyObject]!,RSSI: NSNumber!) {

    if *this is a known device* {
        connectToPeripheral(peripheral)
        return
    }

    [...] // varIoUs stuff to make something a known device,this works
}

所以继续前进,我们得到:

func connectToPeripheral(peripheral: CBPeripheral) {
    println("connecting to \(peripheral.identifier)")

    [...] // saving the peripheral in an array along the way so it is being retained

    centralManager.connectPeripheral(peripheral,options: nil)
}

Yupp,这成功了,所以我得到确认并开始发现服务:

func centralManager(central: CBCentralManager!,didConnectPeripheral peripheral: CBPeripheral!) {        
    println("Connected \(peripheral.name)")

    peripheral.delegate = self

    println("connected to \(peripheral)")
    peripheral.discoverServices([BluetoothConstants.MY_SERVICE_UUID])
}

这也有效,因为该委托方法也被调用

func peripheral(peripheral: CBPeripheral!,didDiscoverServices error: NSError!) {

    if peripheral.services != nil {
        for service in peripheral.services {
            println("discovered service \(service)")
            let serviceObject = service as! CBService

            [...] // Discover the Characteristic to send controls to,this works
            peripheral.discoverCharacteristics([BluetoothConstants.MY_CHARACTERISTIC_NOTIFICATION_UUID],forService: serviceObject)

           [...] // Some unneccessary stuff about command caches
        }
    }
}

你知道什么:特征被发现了!

func peripheral(peripheral: CBPeripheral!,didDiscoverCharacteristicsForService service: CBService!,error: NSError!) {
    for characteristic in service.characteristics {
        let castCharacteristic = characteristic as! CBCharacteristic

        characteristics.append(castCharacteristic) // Retaining the characteristic in an Array as well,not sure if I need to do this

        println("discovered characteristic \(castCharacteristic)")
        if *this is the control characteristic* {
            println("control")
        } else if castCharacteristic.UUID.UUIDString == BluetoothConstants.MY_CHARACTERISTIC_NOTIFICATION_UUID.UUIDString {
            println("notification")
            peripheral.setNotifyValue(true,forCharacteristic: castCharacteristic)
        } else {
            println(castCharacteristic.UUID.UUIDString) // Just in case
        }
        println("following properties:")

        // Just to see what we are dealing with
        if (castCharacteristic.properties & CBCharacteristicProperties.Broadcast) != nil {
            println("broadcast")
        }
        if (castCharacteristic.properties & CBCharacteristicProperties.Read) != nil {
            println("read")
        }
        if (castCharacteristic.properties & CBCharacteristicProperties.WriteWithoutResponse) != nil {
            println("write without response")
        }
        if (castCharacteristic.properties & CBCharacteristicProperties.Write) != nil {
            println("write")
        }
        if (castCharacteristic.properties & CBCharacteristicProperties.Notify) != nil {
            println("notify")
        }
        if (castCharacteristic.properties & CBCharacteristicProperties.Indicate) != nil {
            println("indicate")
        }
        if (castCharacteristic.properties & CBCharacteristicProperties.AuthenticatedSignedWrites) != nil {
            println("authenticated signed writes ")
        }
        if (castCharacteristic.properties & CBCharacteristicProperties.ExtendedProperties) != nil {
            println("indicate")
        }
        if (castCharacteristic.properties & CBCharacteristicProperties.NotifyEncryptionrequired) != nil {
            println("notify encryption required")
        }
        if (castCharacteristic.properties & CBCharacteristicProperties.IndicateEncryptionrequired) != nil {
            println("indicate encryption required")
        }

        peripheral.discoverDescriptorsForCharacteristic(castCharacteristic) // Do I need this?
    }
}

现在控制台输出到这里看起来像这样:

connected to <CBPeripheral: 0x1740fc780,identifier = $FOO,name = $SomeName,state = connected>
discovered service <CBService: 0x170272c80,isPrimary = YES,UUID = $BAR>
[...]
discovered characteristic <CBCharacteristic: 0x17009f220,UUID = $BARBAR properties = 0xA,value = (null),notifying = NO>
control
following properties:
read
write
[...]
discovered characteristic <CBCharacteristic: 0x17409d0b0,UUID = $BAZBAZ,properties = 0x1A,notifying = NO>
notification
following properties:
read
write
notify
[...]
discovered DescriptorsForCharacteristic
[]
updateNotification: false

嘿!它说updateNotification是假的.它来自哪里?为什么,这是我对setNotify的回调…:

func peripheral(peripheral: CBPeripheral!,didUpdateNotificationStateForCharacteristic characteristic: CBCharacteristic!,error: NSError!) {

    println("updateNotification: \(characteristic.isNotifying)")
}

是什么赋予了?我告诉它要通知!为什么不通知?让我们在println的行中设置一个断点并检查错误对象:

(lldb) po error
Error Domain=CBATTErrorDomain Code=10 "The attribute could not be found." UserInfo=0x17026eac0 {NSLocalizedDescription=The attribute could not be found.}

好的,所以这让我没有想法.我无法找到有关该错误代码的相关线索.自从我尝试为之前发现的特征设置通知以来,我无法理解描述本身,因此它必须存在,对吧?此外,在Android上似乎可以订阅通知,所以我想我可以排除设备的问题……或者我可以吗?有关这方面的任何线索都非常感谢!

解决方法

对我来说问题是我使用另一个Android设备作为外围设备并且需要实现配置描述符.看这里:
https://stackoverflow.com/a/25508053/599743

猜你在找的iOS相关文章