Swift中蓝牙读取的特征值

Swift中蓝牙读取的特征值,swift,bluetooth,nsdata,btle,Swift,Bluetooth,Nsdata,Btle,我正在尝试从BT设备读取数据并将其转换为字符串 <CBCharacteristic: 0x1700a2e80, UUID = 2A9D, properties = 0x20, value = <02ac08e1 07010a14 0029>, notifying = YES> 但我的u16为空,即使characteristic.value包含 (lldb) dp characteristic.value! as NSData <02ac08e1 07010a14

我正在尝试从BT设备读取数据并将其转换为字符串

<CBCharacteristic: 0x1700a2e80, UUID = 2A9D, properties = 0x20, value = <02ac08e1 07010a14 0029>, notifying = YES>
但我的u16为空,即使characteristic.value包含

(lldb) dp characteristic.value! as NSData
<02ac08e1 07010a14 0029>
(lldb)dp characteristic.value!作为NSData
有人能给我指出正确的方向吗?

这可不太容易

您可能需要这样写:

let data = Data([0x02,0xac,0x08,0xe1,0x07,0x01,0x0a,0x14,0x00,0x29])

struct DataReader {
    var data: Data
    var offset: Int = 0

    mutating func read() -> UInt8 {
        let result = data[offset]
        offset += MemoryLayout<UInt8>.size
        return result
    }
    mutating func read() -> UInt16 {
        let subdata = data.subdata(in: offset..<offset+MemoryLayout<UInt16>.size)
        let result: UInt16 = subdata.withUnsafeBytes {(bytes: UnsafePointer<UInt16>) in
            bytes.pointee.littleEndian
        }
        offset += MemoryLayout<UInt16>.size
        return result
    }
}

typealias  BLEUserID = UInt8

struct BLEDateTime {
    var year: UInt16
    var month: UInt8
    var day: UInt8
    var hours: UInt8
    var minutes: UInt8
    var seconds: UInt8
}
extension DataReader {
    mutating func read() -> BLEDateTime {
        let year: UInt16 = read()
        let month: UInt8 = read()
        let day: UInt8 = read()
        let hours: UInt8 = read()
        let minutes: UInt8 = read()
        let seconds: UInt8 = read()
        return BLEDateTime(year: year, month: month, day: day, hours: hours, minutes: minutes, seconds: seconds)
    }
}
struct WeightMeasurement: CustomStringConvertible {
    struct Flags: OptionSet {
        var rawValue: UInt8
        init(rawValue: UInt8) {
            self.rawValue = rawValue
        }
        static let measurementImperial = Flags(rawValue: 1<<0)
        static let timeStampPresent = Flags(rawValue: 1<<1)
        static let userIDPresent = Flags(rawValue: 1<<2)
        static let bmiAndHeightPresent = Flags(rawValue: 1<<3)
    }
    var isMeasuremntImperial: Bool
    var weight: Decimal
    var timeStamp: BLEDateTime?
    var userID: BLEUserID?
    var bmi: Decimal?
    var height: Decimal?

    var description: String {
        return weight.description
    }
}
extension DataReader {
    mutating func read() -> WeightMeasurement {
        let flags = WeightMeasurement.Flags(rawValue: read())
        let isMeasuremntImperial = flags.contains(.measurementImperial)
        let weight: Decimal
        if isMeasuremntImperial {
            weight = Decimal(read() as UInt16) * Decimal(string: "0.01")!
        } else {
            //SI
            weight = Decimal(read() as UInt16) * Decimal(string: "0.005")!
        }
        var timeStamp: BLEDateTime?
        if flags.contains(.timeStampPresent) {
            timeStamp = read()
        }
        var userID: BLEUserID?
        if flags.contains(.userIDPresent) {
            userID = read()
        }
        var bmi: Decimal?
        var height: Decimal?
        if flags.contains(.bmiAndHeightPresent) {
            bmi = Decimal(read() as UInt16) * Decimal(string: "0.1")!
            if isMeasuremntImperial {
                height = Decimal(read() as UInt16) * Decimal(string: "0.1")!
            } else {
                //SI
                height = Decimal(read() as UInt16) * Decimal(string: "0.001")!
            }
        }
        return WeightMeasurement(isMeasuremntImperial: isMeasuremntImperial, weight: weight, timeStamp: timeStamp, userID: userID, bmi: bmi, height: height)
    }
}

var reader = DataReader(data: data, offset: 0)
let weightMeasurement: WeightMeasurement = reader.read()
print(weightMeasurement) //->11.1
print(weightMeasurement.timeStamp!) //->BLEDateTime(year: 2017, month: 1, day: 10, hours: 20, minutes: 0, seconds: 41)
let data=data([0x02,0xac,0x08,0xe1,0x07,0x01,0x0a,0x14,0x00,0x29])
结构数据读取器{
var数据:数据
变量偏移量:Int=0
变异func read()->UInt8{
让结果=数据[偏移量]
偏移量+=MemoryLayout.size
返回结果
}
变异func read()->UInt16{
设subdata=data.subdata(in:offset..BLEDateTime{
年份:UInt16=read()
月份:UInt8=read()
let day:UInt8=read()
让小时数:UInt8=read()
分钟数:UInt8=read()
让秒数:UInt8=read()
return BLEDateTime(年:年,月:月,日:日,小时:小时,分钟:分,秒:秒)
}
}
结构权重度量:CustomStringConvertible{
结构标志:OptionSet{
var原始值:UInt8
初始化(原始值:UInt8){
self.rawValue=rawValue
}

静态let measurementImperial=Flags(原始值:1谢谢!我下班回家后再试试。谢谢!
let data = Data([0x02,0xac,0x08,0xe1,0x07,0x01,0x0a,0x14,0x00,0x29])

struct DataReader {
    var data: Data
    var offset: Int = 0

    mutating func read() -> UInt8 {
        let result = data[offset]
        offset += MemoryLayout<UInt8>.size
        return result
    }
    mutating func read() -> UInt16 {
        let subdata = data.subdata(in: offset..<offset+MemoryLayout<UInt16>.size)
        let result: UInt16 = subdata.withUnsafeBytes {(bytes: UnsafePointer<UInt16>) in
            bytes.pointee.littleEndian
        }
        offset += MemoryLayout<UInt16>.size
        return result
    }
}

typealias  BLEUserID = UInt8

struct BLEDateTime {
    var year: UInt16
    var month: UInt8
    var day: UInt8
    var hours: UInt8
    var minutes: UInt8
    var seconds: UInt8
}
extension DataReader {
    mutating func read() -> BLEDateTime {
        let year: UInt16 = read()
        let month: UInt8 = read()
        let day: UInt8 = read()
        let hours: UInt8 = read()
        let minutes: UInt8 = read()
        let seconds: UInt8 = read()
        return BLEDateTime(year: year, month: month, day: day, hours: hours, minutes: minutes, seconds: seconds)
    }
}
struct WeightMeasurement: CustomStringConvertible {
    struct Flags: OptionSet {
        var rawValue: UInt8
        init(rawValue: UInt8) {
            self.rawValue = rawValue
        }
        static let measurementImperial = Flags(rawValue: 1<<0)
        static let timeStampPresent = Flags(rawValue: 1<<1)
        static let userIDPresent = Flags(rawValue: 1<<2)
        static let bmiAndHeightPresent = Flags(rawValue: 1<<3)
    }
    var isMeasuremntImperial: Bool
    var weight: Decimal
    var timeStamp: BLEDateTime?
    var userID: BLEUserID?
    var bmi: Decimal?
    var height: Decimal?

    var description: String {
        return weight.description
    }
}
extension DataReader {
    mutating func read() -> WeightMeasurement {
        let flags = WeightMeasurement.Flags(rawValue: read())
        let isMeasuremntImperial = flags.contains(.measurementImperial)
        let weight: Decimal
        if isMeasuremntImperial {
            weight = Decimal(read() as UInt16) * Decimal(string: "0.01")!
        } else {
            //SI
            weight = Decimal(read() as UInt16) * Decimal(string: "0.005")!
        }
        var timeStamp: BLEDateTime?
        if flags.contains(.timeStampPresent) {
            timeStamp = read()
        }
        var userID: BLEUserID?
        if flags.contains(.userIDPresent) {
            userID = read()
        }
        var bmi: Decimal?
        var height: Decimal?
        if flags.contains(.bmiAndHeightPresent) {
            bmi = Decimal(read() as UInt16) * Decimal(string: "0.1")!
            if isMeasuremntImperial {
                height = Decimal(read() as UInt16) * Decimal(string: "0.1")!
            } else {
                //SI
                height = Decimal(read() as UInt16) * Decimal(string: "0.001")!
            }
        }
        return WeightMeasurement(isMeasuremntImperial: isMeasuremntImperial, weight: weight, timeStamp: timeStamp, userID: userID, bmi: bmi, height: height)
    }
}

var reader = DataReader(data: data, offset: 0)
let weightMeasurement: WeightMeasurement = reader.read()
print(weightMeasurement) //->11.1
print(weightMeasurement.timeStamp!) //->BLEDateTime(year: 2017, month: 1, day: 10, hours: 20, minutes: 0, seconds: 41)