Reputation: 966
I am using Core Bluetooth in an iOS app using Xcode and Swift to get data from a Muse 2. The process works except the didUpdateValueFor callback function doesn't fire. The didUpdateNotificationStateFor callback function fires, and when I print the characteristics, they show that they are notifying. I have done the same thing with a Polar H10, and it works just fine.
One of the characteristics has a write without response property. What would I write to the characteristic?
Do the makers of Muse 2 Headband share information about their protocol?
import UIKit
import CoreBluetooth
class ViewController: UIViewController {
var workerQueue = DispatchQueue(label: "us.utili.TrialMuse.workerQueue")
var centralManager: CBCentralManager! = nil
var muse: CBPeripheral! = nil
override func viewDidLoad() {
super.viewDidLoad()
let options: [String: Any] = [CBCentralManagerOptionShowPowerAlertKey: true]
self.centralManager = CBCentralManager(delegate: self, queue: workerQueue, options: options)
self.centralManager.delegate = self
}
}
extension ViewController: CBCentralManagerDelegate {
func centralManagerDidUpdateState(_ central: CBCentralManager) {
print("centralManagerDidUpdateState")
switch central.state {
case .unknown:
print("central.state is .unknown")
case .resetting:
print("central.state is .resetting")
case .unsupported:
print("central.state is .unsupported")
case .unauthorized:
print("central.state is .unauthorized")
case .poweredOff:
print("central.state is .poweredOff")
case .poweredOn:
print("central.state is .poweredOn")
centralManager.scanForPeripherals(withServices: nil)
@unknown default:
print("switch central.state @unknown default:")
}
}
func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
print("didDiscover")
print("peripheral description:", peripheral.description)
if let peripheralName = peripheral.name, peripheralName == "Muse-7EF5" {
muse = peripheral
muse.delegate = self
central.stopScan()
central.connect(muse, options: nil)
}
}
func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
print("didConnect")
print("peripheral:", peripheral)
peripheral.discoverServices(nil)
}
}
extension ViewController: CBPeripheralDelegate {
func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
print("didDiscoverServices")
guard let services = peripheral.services else {
return
}
print("services:")
for service in services {
print("\tservice description:", service.description)
peripheral.discoverCharacteristics(nil, for: service)
}
}
func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
print("didDiscoverCharacteristicsFor")
guard let characteristics = service.characteristics else {
return
}
for characteristic in characteristics {
print("characteristic description:", characteristic.description)
if characteristic.properties.contains(.broadcast) {
print("\tbroadcast")
}
if characteristic.properties.contains(.read) {
print("\tread")
}
if characteristic.properties.contains(.writeWithoutResponse) {
print("\twrite without response")
}
if characteristic.properties.contains(.write) {
print("\twrite")
}
if characteristic.properties.contains(.notify) {
print("\tnotify")
}
if characteristic.properties.contains(.indicate) {
print("\tindicate")
}
if characteristic.properties.contains(.authenticatedSignedWrites) {
print("\tauthenticated signed writes")
}
if characteristic.properties.contains(.extendedProperties) {
print("\textended properties")
}
if characteristic.properties.contains(.notifyEncryptionRequired) {
print("\tnotify encryption required")
}
if characteristic.properties.contains(.indicateEncryptionRequired) {
print("\tindicate encryption required")
}
if characteristic.properties.contains(.notify) {
peripheral.setNotifyValue(true, for: characteristic)
}
if characteristic.properties.contains(.read) {
peripheral.readValue(for: characteristic)
}
}
}
func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
print("didUpdateValueFor")
if let error = error {
print("error:", error)
}
guard characteristic.value != nil else {
return
}
print("characteristic description:", characteristic.description)
}
func peripheral(_ peripheral: CBPeripheral, didUpdateNotificationStateFor characteristic: CBCharacteristic, error: Error?) {
print("didUpdateNotificationStateFor")
print("characteristic description:", characteristic.description)
}
}
Here is the output in the debug window:
centralManagerDidUpdateState
central.state is .poweredOn
didDiscover
peripheral description: <CBPeripheral: 0x282365cc0, identifier = 151183C1-EB98-03BF-A37A-5AC3E7752F5D, name = (null), state = disconnected>
didDiscover
peripheral description: <CBPeripheral: 0x282365d60, identifier = 573D0EDD-7D27-97D6-5D03-E49C9F505847, name = Muse-7EF5, state = disconnected>
didConnect
peripheral: <CBPeripheral: 0x282365d60, identifier = 573D0EDD-7D27-97D6-5D03-E49C9F505847, name = Muse-7EF5, state = connected>
didDiscoverServices
services:
service description: <CBService: 0x280724100, isPrimary = YES, UUID = FE8D>
didDiscoverCharacteristicsFor
characteristic description: <CBCharacteristic: 0x28367c840, UUID = 273E0001-4C4D-454D-96BE-F03BAC821358, properties = 0x14, value = (null), notifying = NO>
write without response
notify
characteristic description: <CBCharacteristic: 0x28367c8a0, UUID = 273E0008-4C4D-454D-96BE-F03BAC821358, properties = 0x10, value = (null), notifying = NO>
notify
characteristic description: <CBCharacteristic: 0x28367c900, UUID = 273E0009-4C4D-454D-96BE-F03BAC821358, properties = 0x10, value = (null), notifying = NO>
notify
characteristic description: <CBCharacteristic: 0x28367c960, UUID = 273E000A-4C4D-454D-96BE-F03BAC821358, properties = 0x10, value = (null), notifying = NO>
notify
characteristic description: <CBCharacteristic: 0x28367c9c0, UUID = 273E000B-4C4D-454D-96BE-F03BAC821358, properties = 0x10, value = (null), notifying = NO>
notify
characteristic description: <CBCharacteristic: 0x28367ca20, UUID = 273E0002-4C4D-454D-96BE-F03BAC821358, properties = 0x10, value = (null), notifying = NO>
notify
characteristic description: <CBCharacteristic: 0x28367ca80, UUID = 273E0003-4C4D-454D-96BE-F03BAC821358, properties = 0x10, value = (null), notifying = NO>
notify
characteristic description: <CBCharacteristic: 0x28367cae0, UUID = 273E0004-4C4D-454D-96BE-F03BAC821358, properties = 0x10, value = (null), notifying = NO>
notify
characteristic description: <CBCharacteristic: 0x28367cb40, UUID = 273E0005-4C4D-454D-96BE-F03BAC821358, properties = 0x10, value = (null), notifying = NO>
notify
characteristic description: <CBCharacteristic: 0x28367cba0, UUID = 273E0006-4C4D-454D-96BE-F03BAC821358, properties = 0x10, value = (null), notifying = NO>
notify
characteristic description: <CBCharacteristic: 0x28367cc00, UUID = 273E0007-4C4D-454D-96BE-F03BAC821358, properties = 0x10, value = (null), notifying = NO>
notify
characteristic description: <CBCharacteristic: 0x28367cc60, UUID = 273E000C-4C4D-454D-96BE-F03BAC821358, properties = 0x10, value = (null), notifying = NO>
notify
characteristic description: <CBCharacteristic: 0x28367ccc0, UUID = 273E000D-4C4D-454D-96BE-F03BAC821358, properties = 0x10, value = (null), notifying = NO>
notify
characteristic description: <CBCharacteristic: 0x28367cd20, UUID = 273E000E-4C4D-454D-96BE-F03BAC821358, properties = 0x10, value = (null), notifying = NO>
notify
characteristic description: <CBCharacteristic: 0x28367cd80, UUID = 273E000F-4C4D-454D-96BE-F03BAC821358, properties = 0x10, value = (null), notifying = NO>
notify
characteristic description: <CBCharacteristic: 0x28367cde0, UUID = 273E0010-4C4D-454D-96BE-F03BAC821358, properties = 0x10, value = (null), notifying = NO>
notify
characteristic description: <CBCharacteristic: 0x28367ce40, UUID = 273E0011-4C4D-454D-96BE-F03BAC821358, properties = 0x10, value = (null), notifying = NO>
notify
didUpdateNotificationStateFor
characteristic description: <CBCharacteristic: 0x28367c840, UUID = 273E0001-4C4D-454D-96BE-F03BAC821358, properties = 0x14, value = (null), notifying = YES>
didUpdateNotificationStateFor
characteristic description: <CBCharacteristic: 0x28367c8a0, UUID = 273E0008-4C4D-454D-96BE-F03BAC821358, properties = 0x10, value = (null), notifying = YES>
didUpdateNotificationStateFor
characteristic description: <CBCharacteristic: 0x28367c900, UUID = 273E0009-4C4D-454D-96BE-F03BAC821358, properties = 0x10, value = (null), notifying = YES>
didUpdateNotificationStateFor
characteristic description: <CBCharacteristic: 0x28367c960, UUID = 273E000A-4C4D-454D-96BE-F03BAC821358, properties = 0x10, value = (null), notifying = YES>
didUpdateNotificationStateFor
characteristic description: <CBCharacteristic: 0x28367c9c0, UUID = 273E000B-4C4D-454D-96BE-F03BAC821358, properties = 0x10, value = (null), notifying = YES>
didUpdateNotificationStateFor
characteristic description: <CBCharacteristic: 0x28367ca20, UUID = 273E0002-4C4D-454D-96BE-F03BAC821358, properties = 0x10, value = (null), notifying = YES>
didUpdateNotificationStateFor
characteristic description: <CBCharacteristic: 0x28367ca80, UUID = 273E0003-4C4D-454D-96BE-F03BAC821358, properties = 0x10, value = (null), notifying = YES>
didUpdateNotificationStateFor
characteristic description: <CBCharacteristic: 0x28367cae0, UUID = 273E0004-4C4D-454D-96BE-F03BAC821358, properties = 0x10, value = (null), notifying = YES>
didUpdateNotificationStateFor
characteristic description: <CBCharacteristic: 0x28367cb40, UUID = 273E0005-4C4D-454D-96BE-F03BAC821358, properties = 0x10, value = (null), notifying = YES>
didUpdateNotificationStateFor
characteristic description: <CBCharacteristic: 0x28367cba0, UUID = 273E0006-4C4D-454D-96BE-F03BAC821358, properties = 0x10, value = (null), notifying = YES>
didUpdateNotificationStateFor
characteristic description: <CBCharacteristic: 0x28367cc00, UUID = 273E0007-4C4D-454D-96BE-F03BAC821358, properties = 0x10, value = (null), notifying = YES>
didUpdateNotificationStateFor
characteristic description: <CBCharacteristic: 0x28367cc60, UUID = 273E000C-4C4D-454D-96BE-F03BAC821358, properties = 0x10, value = (null), notifying = YES>
didUpdateNotificationStateFor
characteristic description: <CBCharacteristic: 0x28367ccc0, UUID = 273E000D-4C4D-454D-96BE-F03BAC821358, properties = 0x10, value = (null), notifying = YES>
didUpdateNotificationStateFor
characteristic description: <CBCharacteristic: 0x28367cd20, UUID = 273E000E-4C4D-454D-96BE-F03BAC821358, properties = 0x10, value = (null), notifying = YES>
didUpdateNotificationStateFor
characteristic description: <CBCharacteristic: 0x28367cd80, UUID = 273E000F-4C4D-454D-96BE-F03BAC821358, properties = 0x10, value = (null), notifying = YES>
didUpdateNotificationStateFor
characteristic description: <CBCharacteristic: 0x28367cde0, UUID = 273E0010-4C4D-454D-96BE-F03BAC821358, properties = 0x10, value = (null), notifying = YES>
didUpdateNotificationStateFor
characteristic description: <CBCharacteristic: 0x28367ce40, UUID = 273E0011-4C4D-454D-96BE-F03BAC821358, properties = 0x10, value = (null), notifying = YES>
Upvotes: 1
Views: 1834
Reputation: 31
I could see that you are checking characteristic.properties.contains(.notify) twice. Just comment these lines
if characteristic.properties.contains(.notify) {
print("\tnotify")
}
As per the swift logic, there is no error in that code. I too had the same problem and to my surprise, just by commenting on those lines, it worked for me. But I got nil value for characteristic in didUpdateValueFor. But in your case, the func itself isn't triggered. Maybe you can just give a try.
But the code doesn't seem to have any issues. It should be an issue from the muse.
Upvotes: 2