IOS蓝牙

1中开发蓝牙的通用系统库。iOS是

2.蓝牙外设必须是4.0以上(2.0需要MFI认证),否则无法开发。蓝牙4.0设备因其低功耗也被称为BLE。

3.CoreBluetooth框架的核心其实是两件事。

3.1外围设备

3.2?中心的

4.服务特性:简而言之,外接蓝牙有几个服务service(服务你可以知道蓝牙有什么),每个服务又有几个特性feature(特性你可以知道来说明这个服务的属性)。

5.描述符用于描述特征变量的属性。例如,描述符可以指定可读的描述,或者特征变量的可接受范围,或者特征变量的特定单位。

?3.1为蓝牙管理创建CBCentralManager的实例;

?3.2搜索和扫描外围设备;

?3.3连接外围设备;

?3.4获取外围服务;

?3.5获取服务的特点;

?3.6从外围设备读取数据;

?3.7向外围设备发送(写入)数据。

?4.1初始化

DISPATCH _ QUEUE _ t central QUEUE = DISPATCH _ QUEUE _ create(" central QUEUE ",DISPATCH _ QUEUE _ SERIAL);

ns dictionary * DIC = @ { cbcentralmanageroptionrestore identifier key:restore identifier };

self . central manager =[[cbcentral manager alloc]initWithDelegate:self queue:central queue options:DIC];

cbcentralmanagementstoreidentifierkey对应于一个唯一的标识字符串,在终止蓝牙进程并恢复连接时使用该字符串。

4.2扫描

/*

?*扫描设备

?*/

-(void)scanForDevices:(NSError * *)错误

{

if(CBCentralManagerStatePoweredOn = = self . centralmanager . state){

//检索连接的服务设备。

ns array * retrieved peripherals =[self。centralManagerretrieveConnectedPeripheralsWithServices:@[self。service uuid]];

for(CB peripheral * peripheral in retrieved peripherals){

//NSLog(@ "检索到的外设:%@ ",外设);

【自我。delegate client:self did discover device:peripheral . identifier];

}

//开始扫描

如果(自我。advertisementUUID) {

【自我。central manager scanForPeripheralsWithServices:@[self。advertisementUUID ]选项:@ { CBCentralManagerScanOptionAllowDuplicatesKey:@ YES }];

}否则{

【自我。centralManager scanForPeripheralsWithServices:nil options:@ { CBCentralManagerScanOptionAllowDuplicatesKey:@ YES }];

//[self . central manager scanForPeripheralsWithServices:nil options:nil];

}

}否则{

如果(错误!= NULL ) {

* error =[NSErrorerrorWithDomain:HCErrorDomaincode:(srvclienterror unknown+self . central manager . state)userInfo:nil];

NSLog(@ "[NSError error with domain:HC error domain code:(srvclienterror unknown+self . central manager . state)userInfo:nil];");

}

}

}

4.3外围设备的发现

-(void)central manager:(cbcentral manager *)central discover peripheral:(CBPeripheral *)peripheral advertisement data:(ns dictionary *)advertisement data RSSI:(ns number *)RSSI {

ns string * peripheral name = peripheral . name;

if(peripheral name = = nil | | peripheral name . length = = 0){

返回;

}

if([peripheralNameisEqualToString:SRV _ CLIENT _ DEV _ NAME]| |[peripheralNameisEqualToString:SRV _ CLIENT _ DFU _ NAME]){

}

}

4.4连接外围设备

//蓝牙连接成功回拨

-(void)central manager:(cbcentral manager *)centraldconnectperipheral:(CBPeripheral *)peripheral {

【自我。central manager stopScan];

peripheral.delegate=自我;

自我。command no = 0;

NSLog(@"[D] CentralManager发现服务。");

NSLog(@“% @”),self。周边);

self .peripheral.delegate = self

【自我。外设发现服务:@[ self。service uuid]];

NSLog(@“% @”),self。service uuid);

//定期获取RSSI

如果(自我。needReadRSSI) {

[self readperipheral RSSI];

如果(!自我。rssiTimer) {

自我。rssiTimer =[ns timer scheduledTimerWithTimeInterval:5.0

?目标:自我

选择器:@selector (readPeripheralRSSI)

用户信息:无

重复:是];

}

}

}

#pragma?马克?连接外围设备-失败

-?(void)central manager:(cbcentral manager?*)中央?didFailToConnectPeripheral:(CB peripheral?*)外设?错误:(n错误?*)错误{

NSLog(@“% @”,?错误);

}

#pragma?马克?取消与外围设备的连接回拨。

-?(void)central manager:(cbcentral manager?*)中央?didisconnectperipheral:(CB peripheral?*)外设?错误:(n错误?*)错误{

NSLog(@“% @”,?周边);

}

4.5?从外围设备获取服务

//发现服务的回调

-(void)peripheral:(CB peripheral *)peripheral ddiscoverservices:(NSError *)错误

{

NSLog(@“% @-didDiscoverServices”,外设);

如果(错误){

NSLog(@ "[E]peripheral didiscoverservices错误:%@ ",error . localized description);

[自我取消连接];

返回;

}

for(CB service * peripheral . services中的服务){

NSLog(@"[D]发现特征。For service = %@ ",service);

[peripheral discover characters:nil for service:service];

}

}

//找到功能的回调

-(void)peripheral:(CB peripheral *)peripheral diddiscovercharactersforservice:(CB service *)服务错误:(NSError *)错误

{

如果(错误){

NSLog(@ "[E]peripheral didiscovercharactersforservice错误:%@ ",error . localized description);

[自我取消连接];

返回;

}

NSLog(@ "[D]peripheral discover characters = % @ ",service.characteristics

//订阅功能

for(CB character istic * service . character istics中的特性){

if(特性.属性& amp(cbcharacterypropertyinotify | cbcharacterypropertypindicate)){

如果(!character ization . is notifying){

如果(【自我。ignoreCharacteristicUUIDscontainsObject:特征。UUID]) {

继续;

}

NSLog(@"[D]启用通知值。For特性= %@ ",特性);

//d订阅功能在数据经常更改时使用setNotifyValue,在数据不经常更改时使用readValueForCharacteristic。

[peripheralsetNotifyValue:YES for characteristic:character istic];

}

}

}

}

//订阅后回调

-(void)peripheral:(CB peripheral *)peripheral diupdatenotificationstateforcharacteristic:(CB character istic *)特征错误:(NSError *)错误

{

如果(错误){

NSLog(@ "[E]peripheral diupdatenotificationstateforcharacterical error:% @ ",error . localized description);

[自我取消连接];

返回;

}

if([self isallcharacternotificationenabled]){

NSLog(@“订阅成功”);

//authorizer request授权验证

【自我。delegate clientiddprepareforoperation:self];

}

//[self . delegate clientiddprepareforoperation:self];

}

4.6?从外围设备读取数据

//外设主动发送数据,包括写命令后主动返回的状态读取数据的回调。

-(void)peripheral:(CB peripheral *)peripheral dupdatevalue for character istic:(CB character istic *)character istic error:(NSError *)error

{

如果(错误){

NSLog(@ "[E]peripheral didupdatevalueforcharacterical error:% @ % @ ",error.localizedDescription,characteristic

[自我取消连接];

[自我清理操作意外];

返回;

}

NSLog(@“% @”,外设);

NSLog(@“% @”,特征);

【自我。委托客户:self diddupdatevalueforcharacteristic:character istic。UUID价值:特性.价值];

如果(【特点。UUIDisEqual:自我。ctrl ptuid]){

if(CTRLPTProgressWaitResp = = self。ctrlptProgress) {

?}

}

?}

4.7?向外围设备发送(写入)数据。

-(BOOL)performOperationSegment:(CB character istic *)特征

{

BOOL isLastSegment

uint 8 _ t segment[20];

uint 16 _ tindex = 0;

uint 16 _ tsegLength;

NSIntegerforwardLength = self . forward flow . length;

if ((forwardLength - self。forwardOffset)>(20个索引)){

isLastSegment =否;

segLength = (20-索引);

}否则{

isLastSegment = YES

segLength = (forwardLength - self。forward offset);

}

memcpy(& amp;段[索引],& ampself .forwardFlow.bytes[ self。forwardOffset],segLength

自我。forward offset+= seg length;

index+= seg length;

ns data * writeData =[ns datadatawithbytes:segment length:index];

NSLog(@"[D] Write value = %@。For characteristic = %@ ",writeData,character istic);

【自我。peripheral write value:writeData for characteristic:character istic type:cbcharacteristwritewithresponse];//对于控件蓝牙来说,数据写入要求很快,writewithspoce的写入时间是writewithspoce的2.3倍,所以尽量重写为writewithspoce,提高写入速度。

return isLastSegment

?}

//是否写成功回调?

-(void)peripheral:(CB peripheral *)peripheral diwritevalueforcharacter istic:(CB character istic *)character istic error:(NSError *)error

{

如果(错误){

NSLog(@ "[E]peripheral diwritevalueforcharacterical error:% @ ",error);

[自我取消连接];

[自我清理操作意外];

返回;

}

NSLog(@“写入成功-%@”,特征);

如果(【特点。UUIDisEqual:自我。ctrl ptuid]){

if(CTRLPTProgressWritting = = self。ctrlptProgress) {

if([self performOperationSegment:character istic]){

自我。ctrlptProgress = CTRLPTProgressWaitResp;

self . backward flow . length = 0;

自我。backwardOffset = 0;

}

}

}

}

4.8如何解析蓝牙数据

//判断是否是第一个包,如果是,取出包长。

if (0== self。backwardOffset & amp& amp长度& gt=2) {

uint 16 _ tcommandLength;

【特性数据getbytes:& amp;commandLengthlength:sizeof(command length)];

offset+= sizeof(command length);

自我。backwardLength = commandLength

【自我。backwardfloappenddata:[characterizedatasubdatawithrange:NSMakeRange(offset,length-offset)]];

}否则{

【自我。backwardfloappenddata:character istic data];

}