IOS核心蓝牙:为特性编写NSData

Posted

技术标签:

【中文标题】IOS核心蓝牙:为特性编写NSData【英文标题】:IOS Core Bluetooth : Writing NSData for Characteristic 【发布时间】:2015-10-02 11:36:07 【问题描述】:

我正在使用以下代码使用 ios 核心蓝牙为蓝牙特性(重置设备)写入 0xDE 值:

...
NSData *bytes = [@"0xDE" dataUsingEncoding:NSUTF8StringEncoding];
[peripheral writeValue:bytes
            forCharacteristic:characteristic
            type:CBCharacteristicWriteWithResponse];
...

我的代码中是否有任何错误,因为值没有正确写入?

【问题讨论】:

【参考方案1】:

Swift 3.0:如果有人想知道 Swift 的格式略有不同,因为 writeValue 可以从数组中获取计数。

let value: UInt8 = 0xDE
let data = Data(bytes: [value])
peripheral.writeValue(data, for: characteristic, type: .withResponse)

【讨论】:

你真是太棒了,伙计!谢谢! :)【参考方案2】:

尝试使用单字节值数组创建数据。

const uint8_t bytes[] = 0xDE;
NSData *data = [NSData dataWithBytes:bytes length:sizeof(bytes)];

这是创建任意常量数据的有用方法。如需更多字节,

const uint8_t bytes[] = 0x01,0x02,0x03,0x04,0x05;
NSData *data = [NSData dataWithBytes:bytes length:sizeof(bytes)];

如果您想使用变量创建要发送的数据,我建议您使用 NSMutableData 并附加您需要的字节。它不是很漂亮,但很容易阅读/理解,尤其是当您在嵌入端匹配一个打包结构时。下面的示例来自一个 BLE 项目,我们在该项目中制作了一个简单的通信协议。

NSMutableData *data = [[NSMutableData alloc] init];

//pull out each of the fields in order to correctly
//serialize into a correctly ordered byte stream
const uint8_t start     = PKT_START_BYTE;
const uint8_t bitfield  = (uint8_t)self.bitfield;
const uint8_t frame     = (uint8_t)self.frameNumber;
const uint8_t size      = (uint8_t)self.size;

//append the individual bytes to the data chunk
[data appendBytes:&start    length:1];
[data appendBytes:&bitfield length:1];
[data appendBytes:&frame    length:1];
[data appendBytes:&size     length:1];

【讨论】:

【参考方案3】:

bensarz 的答案几乎是正确的。除了一件事:你不应该使用sizeof(int) 作为NSData 的长度。 int 的大小为 4 或 8 个字节(取决于架构)。如果您想发送 1 个字节,请改用 uint8_tByte

uint8_t byteToWrite = 0xDE;
NSData *data = [[NSData alloc] initWithBytes:&byteToWrite length:sizeof(&byteToWrite)];
[peripheral writeValue:data
     forCharacteristic:characteristic
                  type:CBCharacteristicWriteWithResponse];

当然你也可以使用int作为变量的类型,但是你必须用长度1来初始化NSData

【讨论】:

【参考方案4】:

此代码将解决问题:

NSData * data = [self  dataWithHexString: @"DE"];
[peripheral writeValue:data forCharacteristic:characteristic                                       
                            type:CBCharacteristicWriteWithResponse];

dataWithHexString 实现:

- (NSData *)dataWithHexString:(NSString *)hexstring

    NSMutableData* data = [NSMutableData data];
    int idx;
    for (idx = 0; idx+2 <= hexstring.length; idx+=2) 
        NSRange range = NSMakeRange(idx, 2);
        NSString* hexStr = [hexstring substringWithRange:range];
        NSScanner* scanner = [NSScanner scannerWithString:hexStr];
        unsigned int intValue;
        [scanner scanHexInt:&intValue];
        [data appendBytes:&intValue length:1];
    
    return data;

【讨论】:

我尝试将其转换为 swift 但它给出了错误。有人可以转换它吗?【参考方案5】:

实际上,您在这里所做的就是将字符串“0xDE”写入特征。如果要使用二进制/八进制表示法,则需要远离字符串。

int integer = 0xDE;
NSData *data = [[NSData alloc] initWithBytes:&integer length:sizeof(integer)];
[peripheral writeValue:data
     forCharacteristic:characteristic
                  type:CBCharacteristicWriteWithResponse];

【讨论】:

感谢您的回答,我尝试了您的解决方案...我收到以下错误:写入值以重置设备错误错误域 = CBATTErrorDomain 代码 = 13“值的长度无效。” UserInfo=NSLocalizedDescription=值的长度无效。

以上是关于IOS核心蓝牙:为特性编写NSData的主要内容,如果未能解决你的问题,请参考以下文章

iOS蓝牙编程指南 -- 核心蓝牙概述

使用核心蓝牙时的问题

iOS Swift Mi Scale 2 蓝牙 称重

核心蓝牙内的可写特性

核心蓝牙特性不更新值

iOS刷新蓝牙特性