我有一个TI传感器标签作为外围设备,以kCBAdvDataManufacturerData的形式广播BLE数据。我想从iOS中的这些数据中提取不同的值。
我在Swift中执行以下操作:
func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber){
for (index, foundPeripheral) in peripherals.enumerated(){
if foundPeripheral.peripheral?.identifier == peripheral.identifier{
peripherals[index].lastRSSI = RSSI
print("AdvertisementData:\(advertisementData)")
return
}
}
let isConnectable = advertisementData["kCBAdvDataIsConnectable"] as! Bool
let displayPeripheral = DisplayPeripheral(peripheral: peripheral, lastRSSI: RSSI, isConnectable: isConnectable)
peripherals.append(displayPeripheral)
tableView.reloadData()
}
}
这就是我在控制台上看到的:
AdvertisementData:"kCBAdvDataIsConnectable":0,"kCBAdvDataManufacturerData":<0d00fe05 0c6f32>,"kCBAdvDataLocalName":CLIMBC
我感兴趣的解码数据是kCBAdvDataManufacturerData:<0d00fe05 0c6f32>,并在屏幕上显示每个字段。具体来说,这就是数字在我的例子中所代表的:
在Android中,我能够解码如下:
private static String getNodeIdFromRawPacket(byte[] manufSpecField) {
if(manufSpecField != null && manufSpecField.length > 1) {
return String.format("%02X", manufSpecField[0]);
}else{
return null;
}
}
private static int getNodeBatteryVoltageFromRawPacket(byte[] manufSpecField){
if(manufSpecField != null && manufSpecField.length > 4) {
return (((((int) manufSpecField[manufSpecField.length - 3]) << 24) >>> 24) << 8) + ((((int) manufSpecField[manufSpecField.length - 2]) << 24) >>> 24);
}else{
return 0;
}
}
private byte[] extractManufacturerSpecificData(byte[] scanRecord, int manufacturer_id){
if(scanRecord != null) {
int ptr = 0;
while (ptr < scanRecord.length && scanRecord[ptr] != 0) {
int field_length = scanRecord[ptr];
if (scanRecord[ptr + 1] == (byte) (0xFF)) { //this is true when the manufacturer specific data field has been found
if (((scanRecord[ptr + 3] << 8) + scanRecord[ptr + 2]) == manufacturer_id) {
byte[] manufacturerSpecificData = new byte[field_length - 3];
System.arraycopy(scanRecord, ptr + 4, manufacturerSpecificData, 0, field_length - 3);
return manufacturerSpecificData;
}
}
ptr += (field_length + 1);
}
return null;
}else{
return null;
}
}
};
我怎样才能做到这一点呢?我是新来的斯威夫特,这就是为什么我发现了一些困难。任何代码片段都是最受欢迎的。
发布于 2017-02-09 20:45:12
看到控制台的输出,advertisementData["kCBAdvDataManufacturerData"]
似乎是一个包含7个字节的NSData
。您可以轻松地以Swift Data
的形式访问它,并且可以使用下标访问Data
中的每个字节:
if let manufacturerData = advertisementData["kCBAdvDataManufacturerData"] as? Data {
assert(manufacturerData.count >= 7)
//0d00 - TI manufacturer ID
//Constructing 2-byte data as little endian (as TI's manufacturer ID is 000D)
let manufactureID = UInt16(manufacturerData[0]) + UInt16(manufacturerData[1]) << 8
print(String(format: "%04X", manufactureID)) //->000D
//fe - the node ID that I have given
let nodeID = manufacturerData[2]
print(String(format: "%02X", nodeID)) //->FE
//05 - state of the node (something that remains constant
let state = manufacturerData[3]
print(String(format: "%02X", state)) //->05
//c6f - is the sensor tag battery voltage
//Constructing 2-byte data as big endian (as shown in the Java code)
let batteryVoltage = UInt16(manufacturerData[4]) << 8 + UInt16(manufacturerData[5])
print(String(format: "%04X", batteryVoltage)) //->0C6F
//32- is the BLE packet counter.
let packetCounter = manufacturerData[6]
print(String(format: "%02X", packetCounter)) //->32
}
发布于 2017-02-09 19:45:10
以下是subdata
3数据方法的一个实现,并举例说明了一个字符串转换为数据,然后拆分成可以转换回字符串的字节:
let input = "505450578"
let data = input.data(using: .utf8)
let manufacturerId:Range<Int> = 0..<2
let nodeId:Range<Int> = 2..<4
let nodeState:Range<Int> = 4..<5
let voltage:Range<Int> = 5..<6
let packetCounter:Range<Int> = 6..<9
let subdata1 = data?.subdata(in: manufacturerId)
let subdata2 = data?.subdata(in: nodeId)
let subdata3 = data?.subdata(in: nodeState)
let subdata4 = data?.subdata(in: voltage)
let subdata5 = data?.subdata(in: packetCounter)
//Results from original given string
let str1 = String(data: subdata1!, encoding:.utf8) //50
let str2 = String(data: subdata2!, encoding:.utf8) //54
let str3 = String(data: subdata3!, encoding:.utf8) //5
let str4 = String(data: subdata4!, encoding:.utf8) //0
let str5 = String(data: subdata5!, encoding:.utf8) //578
发布于 2019-05-28 11:18:14
为Swift更新:
let yourServiceUUIDString = "FFF0"
if let mAdvData = advertisementData["kCBAdvDataServiceUUIDs"] as? [AnyObject], (mAdvData.contains { ($0 as? CBUUID)?.uuidString == yourServiceUUIDString}) {
print("BLE device found..!")
}
https://stackoverflow.com/questions/42140636
复制相似问题