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