要想APP在后台长时间运行,可以用蓝牙模式


在info.plist中添加“ Required background modes ”属性,并在该属性下添加两个item,“ App communicates using CoreBluetooth ”和“ App communicates using CoreBluetooth ”,这样就能实现长时间后台运行了。


 一、中心扫描周边
1、创建中心管理员:  

manager=[[ 
 CBCentralManager 
   
 alloc 
 ]  
 initWithDelegate 
 : 
 self 
   
 queue 
 : 
 nil 
 ];
 创建后,系统将自动根据手机硬件情况,在manager的delegate中处理回调函数:
 
 void) centralManagerDidUpdateState:(CBCentralManager *)central{

 }

针对参数central的state属性,0-5的值,有APP做出提示(state<5)或进一步的操作(state==5)

如果state等于5(

CBCentralManagerStatePoweredOn )则进行第二步----


2、扫描周边广播的相关服务
注:如果你不知道怎么设置UUID,你可以用终端命令UUIDGEN,来生成UUID

[manager 
   
 scanForPeripheralsWithServices 
 :(这里填写对应服务的UUID数组) 
   
 options 
 : 
 @{ 
 CBCentralManagerScanOptionAllowDuplicatesKey 
 : [ 
 NSNumber 
  
 numberWithBool 
 : 
 NO 
 ] 
 } 
 ];
一旦扫描到uuid数组中的某服务,系统则调用代理的
 
 - ( 
 void 
 ) centralManager:( 
 CBCentralManager 
  *)central didDiscoverPeripheral:( 
 CBPeripheral 
  *)peripheral advertisementData:( 
 NSDictionary 
  *)advertisementData RSSI:( 
 NSNumber 
  *)RSSI
{

 }

   
在函数中对perial的uuid,server数组进行筛选处理,如果是对应的周边,可以停止搜索并连接该设备

[manager stopScan];
[manager connectPeripheral:peripheral options:@{CBConnectPeripheralOptionNotifyOnDisconnectionKey: [NSNumbernumberWithBool:YES]}]; 

 连上设备后将自动调用回调,
 - (void) centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral{
 }


在函数里可以进行第三步-----

3、查找该设备的指定服务

[peripheral discoverServices:指定服务uuid数组];
操作后,系统自动回调:- (void) peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError*)error {

 }


在函数里,对peripheral的services的uuid进行筛选分别处理,然后对相应的sercice进一步操作,第四步----

4、查找指定服务的指定特征值

[peripheral discoverCharacteristics:特征值uuid数组 forService:指定服务uuid];


系统将自动回调


void) peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError*)error{


 }



至此,已经定位了服务、也定位好了对应服务的特征值,准备工作基本完毕,只需要在该函数里做出相应处理即可  第五步

5、处理指定服务的指定特征值

[peripheral setNotifyValue:YES forCharacteristic:某个特征值];//监听变化
或者 [self.peripheral readValueForCharacteristic:某个特征值];//即时读取
蓝牙模块接收到数据后,处理回调:- (void) peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
 {
 }
NSData  *data=[characteristic value];



接下来 你想怎么处理data,怎么解析,就是根据不同APP不同对待了。 




 


二、周边广播服务


1、创建周边管理员:

 

self.manager=[[CBPeripheralManager alloc] initWithDelegate:self queue:nil];
同样这将使得系统自动调用:-(void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral;
当peripheral的state为5的时候,则可以进行一个广播配置,
 首先得创建至少一个需要广播的服务: 
CBUUID *serverUUID=[CBUUID UUIDWithString:UUID_SERVER];
     _service=[[CBMutableService alloc] initWithType:serverUUID primary:YES]; 
其次,给这个服务添加特征值:
    CBUUID *characterUUID=[CBUUID UUIDWithString:UUID_CHRACT];     _characteristic=[[CBMutableCharacteristic alloc] initWithType:characterUUID properties:CBCharacteristicPropertyRead value:nilpermissions:CBAttributePermissionsReadable];
    [_service setCharacteristics:@[_characteristic]];



这里可以看到,特征值是一个数组,也即,我们可以给某个服务添加多个特征值

最后将服务添加到周边: 

[_manager addService:_service];
我们可以用这个方法,给一个周边添加多个服务,添加完后,系统将自动调用:-(void)peripheralManager:(CBPeripheralManager *)peripheral didAddService:(CBService *)service error:(NSError *)error{

 }


如果无error,那接下来,我们就可以进行第二步操作了----
2、广播周边服务: 

[_manager startAdvertising:广播数据字典]; 
字典如:@{CBAdvertisementDataLocalNameKey:@"CimBT",CBAdvertisementDataServiceUUIDsKey:@[service.UUID]}



以上方法调用后,系统将自动回调:

-(void)peripheralManagerDidStartAdvertising:(CBPeripheralManager *)peripheral error:(NSError *)error {

 }


这里注意,如果你用手机、pad广播一些蓝牙联盟规定的uuid,比如血压计、电池、心率计等,则会出错,同时,广播的字典需要准确设置。
到此,你就能互相搜索到两台带蓝牙的设备了。

中心相关的其他关键方法

1、- (void)writeValue:(NSData *)data forCharacteristic:(CBCharacteristic *)characteristic type:(CBCharacteristicWriteType)type;(比如给血压计设置属性,如测量间隔)
当周边收到这个命令后会操作回调:void)peripheralManager:(CBPeripheralManager*)manager didReceiveWriteRequests:(NSArray *)requests
 {
   //解析request的value值  [self.manager respondToRequest:request withResult:CBATTErrorSuccess];  
 }
 2、- (void)readValueForCharacteristic:(CBCharacteristic *)characteristic;(如读取血压计的某些属性,如测量间隔,血压值等))



当周边收到这个命令后会操作回调:

void)peripheralManager:(CBPeripheralManager*)manager didReceiveReadRequest:(CBATTRequest *)request{
 //在这里设置request 的value属性即可,
 [周边管理器 respondToRequest:request withResult:CBATTErrorSuccess]; }

3、停止扫描

- (void)stopScan;
4、断开连接

- (void)cancelPeripheralConnection:(CBPeripheral *)peripheral;  
5、- (void)retrievePeripherals:(NSArray *)peripheralUUIDs;//在已知uuid的情况下,重新连接

 
附二:周边相关的其他关键方法
1、周边发送数据:

BOOL ret=[self.manager updateValue:data forCharacteristic:特征值 onSubscribedCentrals:nil];



2、停止广播
 - (void)stopAdvertising; 

代理方法:

- (void)peripheralManager:(CBPeripheralManager*)manager central:(CBCentral*)central didSubscribeToCharacteristic:(CBCharacteristic *)characteristic  {
 //设备特征被订阅了,即处于可收发状态

 }void)peripheralManager:(CBPeripheralManager*)manager central:(CBCentral*)central didUnsubscribeFromCharacteristic:(CBCharacteristic *)characteristic{
 //取消订阅了
 }