Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
589 views
in Technique[技术] by (71.8m points)

ios - Reading a BLE Peripheral Characteristic and checking its value?

I'm writing an app using Swift on Xcode that connects to a bluetooth BLE peripheral. I've established a connection to a the device, and want to read some data from a specific characteristic (specifically FFF1 in service UUID FFF0).

I'm able to request a read of characteristics using the following code if the characteristic that I want to find info for is characteristicx:

peripheral.readValueForCharacteristic(charactericsx)

What I want to know is this: How do I check that this read value is what I'm looking for. I want to be able to do an if statement to check my value against the discovered value for that characteristic.

Eg: If discovered value is X then do something, else if discovered value is Y then do something else.

That's not a very good explanation of what I want to do, but I hope you get the gist.

Anyone know how to go about doing this?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Updated For Swift3

After you execute that method, the delegate of your peripheral is going to asynchronously receive the peripheral(_:didUpdateValueFor:error:) method. In that method you can query the value of the passed characteristic parameter. value will be an NSData which you can pull the bytes out of. E.g.

// MARK: - CBPeripheralDelegate
func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
    if let e = error {
        print("ERROR didUpdateValue (e)")
        return
    }
    guard let data = characteristic.value else { return }
    ...
}

The value method actually returns an Optional around the expected Data, so a let guard is the way to go.

Usually a characteristic will have a simple value encoded in it's up-to-20-byte Data payload. E.g. maybe it's a simple UInt16 counter. To

To convert between these Data glumps and meaningful numbers, have a look at the answer to round trip Swift number types to/from Data (I've included my own implementation of that below).

So for example, if you know that the characteristic of interest is some counter that is a meant to be extracted as a UInt16, I would fill out the above example with something like:

// MARK: - CBPeripheralDelegate
func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
    if let e = error {
        print("ERROR didUpdateValue (e)")
        return
    }
    guard let data = characteristic.value else { return }
    print("counter is (UInt16(data:data))")
}



// Data Extensions:
protocol DataConvertible {
    init(data:Data)
    var data:Data { get }
}

extension DataConvertible {
    init(data:Data) {
        guard data.count == MemoryLayout<Self>.size else {
            fatalError("data size ((data.count)) != type size ((MemoryLayout<Self>.size))")
        }
        self = data.withUnsafeBytes { $0.pointee }
    }

    var data:Data {
        var value = self
        return Data(buffer: UnsafeBufferPointer(start: &value, count: 1))
    }
}

extension UInt8:DataConvertible {}
extension UInt16:DataConvertible {}
extension UInt32:DataConvertible {}
extension Int32:DataConvertible {}
extension Int64:DataConvertible {}
extension Double:DataConvertible {}
extension Float:DataConvertible {}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...