ios - Subscribing for notifications from a CBCharacteristic does not work -
first things first: running osx 10.10.4, ios 4, xcode 6.3.2, iphone 6, swift
short story: have bluetooth le device here want receive notifications when values of characteristic change, e.g. user input. trying subscribe not succeed, rather yields error error domain=cbatterrordomain code=10 "the attribute not found."
long story: so, have bluetoothmanager class in start scanning peripherals $cbcentralmanager.state
.poweredon
. that's easy, i'm citizen , scan service want
centralmanager.scanforperipheralswithservices([serviceuuid], options: nil)
hoping succeed, implemented following delegate method:
func centralmanager(central: cbcentralmanager!, diddiscoverperipheral peripheral: cbperipheral!, advertisementdata: [nsobject : anyobject]!, rssi: nsnumber!) { if *this known device* { connecttoperipheral(peripheral) return } [...] // various stuff make known device, works }
so moving along, to:
func connecttoperipheral(peripheral: cbperipheral) { println("connecting \(peripheral.identifier)") [...] // saving peripheral in array along way being retained centralmanager.connectperipheral(peripheral, options: nil) }
yupp, succeeds, confirmation , start discover service:
func centralmanager(central: cbcentralmanager!, didconnectperipheral peripheral: cbperipheral!) { println("connected \(peripheral.name)") peripheral.delegate = self println("connected \(peripheral)") peripheral.discoverservices([bluetoothconstants.my_service_uuid]) }
which works, since delegate method gets called well:
func peripheral(peripheral: cbperipheral!, diddiscoverservices error: nserror!) { if peripheral.services != nil { service in peripheral.services { println("discovered service \(service)") let serviceobject = service as! cbservice [...] // discover characteristic send controls to, works peripheral.discovercharacteristics([bluetoothconstants.my_characteristic_notification_uuid], forservice: serviceobject) [...] // unneccessary stuff command caches } } }
and know: characteristic gets discovered!
func peripheral(peripheral: cbperipheral!, diddiscovercharacteristicsforservice service: cbservice!, error: nserror!) { characteristic in service.characteristics { let castcharacteristic = characteristic as! cbcharacteristic characteristics.append(castcharacteristic) // retaining characteristic in array well, not sure if need println("discovered characteristic \(castcharacteristic)") if *this 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) // in case } println("following properties:") // see dealing 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) // need this? } }
now console output until here looks this:
connected <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, value = (null), notifying = no> notification following properties: read write notify [...] discovered descriptorsforcharacteristic [] updatenotification: false
hey! says updatenotification
false
. come from? why, it's callback setnotify...
:
func peripheral(peripheral: cbperipheral!, didupdatenotificationstateforcharacteristic characteristic: cbcharacteristic!, error: nserror!) { println("updatenotification: \(characteristic.isnotifying)") }
what gives? told notifying! why isn't notifying? let's set breakpoint in line println , check out error object:
(lldb) po error error domain=cbatterrordomain code=10 "the attribute not found." userinfo=0x17026eac0 {nslocalizeddescription=the attribute not found.}
ok, leaves me out of ideas. wasn't able finde relevant clues regarding error code. description cannot fathom since tried set notification characteristic discovered earlier, hence must exist, right? also, on android seems possible subscribe notifications, guess can rule out problems device... or can i? clues regarding appreciated!
for me issue was using android device peripheral , needed implement configuration descriptor. see here: https://stackoverflow.com/a/25508053/599743
Comments
Post a Comment