CoreBluetooth的API是基于BLE4.0的标准的,从iphone4s往后的设备支持,还有iPhone iOS6的模拟器也支持。

一,外设(Peripheral)和中央(Central)

CoreBluetooth框架的核心就是peripheral(外设)和central(中心)。

比如,通过手机和智能手表通信,那么手机就是Central,手表就是Peripheral。可以认为外设是一个广播数据的设备,他广播到外部世界说他这儿有数据,并且也说明了能提供的服务。另一边,中央开始扫描附近有没有服务,如果中央发现了想要的服务,就会请求连接该外设,一旦连接建立成功,两个设备之间就开始交换传输数据了。

在具体的使用场景下,每一个外设都通过唯一的设备UUID来彼此区分,也可以保存下来作为重连的凭据,在第四部分具体说明。 

二,服务(Service)和特征值(Characteristic)

每个BLE4.0设备必然包含一个或多个服务,每个服务下面又包含若干个特征。特征是与外界交互的最小单位。比如说一只智能手表,用特征值A来描述自己的出厂信息,用特征值B来收发数据等。

服务和特征值都是用UUID来唯一标识的,UUID是一个16bit或者128bit的值。国际蓝牙组织为一些很典型的设备(比如测量心跳和血压的设备)规定了标准的service UUID,当然还有很多设备并不在这个标准列表里,比如我在开发中用到的智能手表,“6e400001-b5a3-f393-e0a9-e50e24dcca9e”用来读写手表信息,“00001530-1212-efde-1523-785feabcd123”用来进行ota升级。

三,BLE通信实现流程

1,建立中心角色

1
2
3
4
5
#import <CoreBluetooth/CoreBluetooth.h>  
 
CBCentralManager *manager;  
 
manager = [[CBCentralManager alloc] initWithDelegate:self queue:nil]; 

 

2,扫描外设(discover)

[manager scanForPeripheralsWithServices:nil options:options];

 

3,连接外设(connect)

1
2
3
4
5
6
7
8
9
10
11
12
13
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI  
{
        if([peripheral.name  isEqualToString:BLE_SERVICE_NAME]){
                [self connect:peripheral];
        }
}        
 
-(BOOL)connect:(CBPeripheral *)peripheral
{
  self.manager.delegate = self;
      [self.manager connectPeripheral:peripheral
                                options:[NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:CBConnectPeripheralOptionNotifyOnDisconnectionKey]];


4,扫描外设中的服务和特征值(discover)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral  
{  
    NSLog(@"Did connect to peripheral: %@", peripheral);  
    _testPeripheral = peripheral;  
 
  
    [peripheral setDelegate:self];  //查×××
    [peripheral discoverServices:nil];      
}  
 
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error  
{  
    NSLog(@"didDiscoverServices");  
    if (error)  
    {  
        NSLog(@"Discovered services for %@ with error: %@", peripheral.name, [error localizedDescription]);  
 
        if ([self.delegate respondsToSelector:@selector(DidNotifyFailConnectService:withPeripheral:error:)])  
            [self.delegate DidNotifyFailConnectService:nil withPeripheral:nil error:nil];            
 
            return;  
    }  
 
    for (CBService *service in peripheral.services)  
    {  
         //发现服务
        if ([service.UUID isEqual:[CBUUID UUIDWithString:UUIDSTR_ISSC_PROPRIETARY_SERVICE]])  
        {  
            NSLog(@"Service found with UUID: %@", service.UUID); //查找特征值
            [peripheral discoverCharacteristics:nil forService:service];  
            break;  
        }            
    }  
 
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error
{
    if (error)
    {
        NSLog(@"Discovered characteristics for %@ with error: %@", service.UUID, [error localizedDescription]);        
 
        [self error];
        return;
    }    
 
    NSLog(@"服务:%@",service.UUID);
    for (CBCharacteristic *characteristic in service.characteristics)
    {
           //发现特征
            if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:@"xxxxxxx"]]) {
                NSLog(@"监听:%@",characteristic); //监听特征值
                [self.peripheral setNotifyValue:YES forCharacteristic:characteristic];
            }         
    }

 

5,与外设做数据交互(读 与 写)  

1
2
3
4
5
6
7
8
9
10
11
12
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
{
    if (error)
    {
        NSLog(@"Error updating value for characteristic %@ error: %@", characteristic.UUID, [error localizedDescription]);
        self.error_b = BluetoothError_System;
        [self error];
 
        return;
    }
    [self decodeData:characteristic.value];

1
2
3
4
5
NSInteger time = [[NSDate date] timeIntervalSince1970];//时间戳
NSMutableData * data = [NSMutableData data];
[data appendBytes:&time length:4];

[self.peripheral writeValue:data forCharacteristic:characteristic type:CBCharacteristicWriteWithoutResponse]; 

读写数据需要考虑具体的使用场景,比如Data,Byte,bit的转换,数据字节序的大小端,数据是否分包。以及对于外设的某些信息的判断:比如说,你要交互的特征,它的properties的值是0x10,表示你只能用订阅的方式来接收数据:

[_testPeripheral setNotifyValue:YES forCharacteristic:_readCharacteristic]; 

四,重连外设(Retrieve)

当外设已处于连接状态,或者与手机配对的状态下,是无法直接通过扫描发现外设的,CoreBluetooth提供了重连恢复的API,它有两种方式,返回值都是外设Peripheral数组:

1.retrievePeripheralsWithIdentifiers,参数是设备的UUID

2.retrieveConnectedPeripheralsWithServices,参数是特定服务的UUID

1
2
3
4
5
6
7
NSUUID *uuid = [[NSUUID alloc] initWithUUIDString:uuidString1];
[uuidArray addObject:(id)uuid]; 
if(uuidArray.count != 0)
{
    NSArray * arr = [_bleCentralManager retrievePeripheralsWithIdentifiers:uuidArray];
}

原文出处:http://www.cnblogs.com/clumsy1006/p/5251992.html