didUpdateValueFor callback function of Core Bluetooth doesn’t fire

Published

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>

Source: Ios

Published
Categorised as core-bluetooth, ios, swift, xcode

Answers

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.


Rita Lehner

Leave a Reply

Your email address will not be published. Required fields are marked *

Still Have Questions?


Our dedicated development team is here for you!

We can help you find answers to your question for as low as 5$.

Contact Us
faq