iOS蓝牙Ble开发

最近做的项目主要是iphone与平常的一些设备进行蓝牙连接,通信等功能。所以整理了一下蓝牙方面的一些知识。

iOS蓝牙开发主要有种方式。

1 GameKit.framework   iOS7之前的蓝牙通讯框架,从iOS7开始过期,但是目前多数应用还是基于此框架。只能用于iOS设备之间,多用于游戏。

2 MultipeerConnectivity.framework  iOS7开始引入的新的蓝牙通讯开发框架,用于取代GameKit。也只能用于iOS设备间,主要用于共享文件。

3 CoreBluetooth.framework  功能强大的蓝牙开发框架,要求设备必须支持蓝牙4.0,可与其他第三方设备进行通信。

4 ExternalAccessory.framework 也可于第三方蓝牙设备交互,但是蓝牙设备必须经过MFI认证,需要有苹果的协议,这就有一定的局限性。

对比明显可以看到CoreBluetooth这个比较好用,并且功能强大,不再局限于iOS设备之间进行传输数据,你可以通过iOS设备向Android、Windows Phone以及其他安装有蓝牙4.0芯片的智能设备传输,因此也是目前智能家居、无线支付等热门智能设备所推崇的技术。我这里介绍一下这个的使用。


CoreBluetooth.framework

从iOS6开始苹果推出了此框架,它专门用于与BLE4.0设备通信,不仅限于iOS设备。

CoreBluetooth框架的核心其实是两个东西,peripheral和central, 可以理解成外设和中心。类似于C/S设计(客户端和服务端),外围设备可以理解为客户端,中央设备可以当作服务端。

外围设备和中央设备在CoreBluetooth中使用CBPeripheralManager和CBCentralManager表示。

CBPeripheralManager:外围设备通常用于发布服务、生成数据、保存数据。外围设备发布并广播服务,告诉周围的中央设备它的可用服务和特征。

CBCentralManager:中央设备使用外围设备的数据。中央设备扫描到外围设备后会就会试图建立连接,一旦连接成功就可以使用这些服务和特征。

外围设备和中央设备之间交互的桥梁是服务(CBService)和特征(CBCharacteristic),二者都有一个唯一的标识UUID(CBUUID类型)来唯一确定一个服务或者特征,每个服务可以拥有多个特征。



左侧表示中央设备,右侧为外围设备。

CBCentralManager  中央设备管理,使用外围设备的数据。中央设备扫描到外围设备后会就会试图建立连接,一旦连接成功就可以使用这些服务和特征。

CBPeripheralManager  外围设备管理,通常用于发布服务、生成数据、保存数据。外围设备发布并广播服务,告诉周围的中央设备它的可用服务和特征。

CBPeripheral  外围设备。

CBCentral      中央设备。

CBServiceCBMutableServic    服务,其中CBMutableServic CBService的子类,只多了一个初始化的方法和两个变量。

CBCharacteristicCBMutableCharacteristic  特征。其中CBMutableCharacteristicCBCharacteristic的子类,多了一个初始化的方法和几个变量。
CBUUID         uuid帮助类。

CBATTRequest      中央发出的读或者写的请求。  


主要说一下中央设备的使用。

iOS 中蓝牙操作主要放在BluetoothManager/GABluetoothManager类中。
该类遵循协议。

CBCentralManagerDelegate 中的方法主要有中央的可用性,扫描到的外围设备,与外围设备连接状态。

CBPeripheralDelegate  中主要是发现服务、特征、描述,读写特征和描述。

初始化中央管理器

self.cbCM = [[CBCentralManager alloc] init];
self.cbCM.delegate = self;

扫描外围设备

NSDictionary *dic = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:NO],CBCentralManagerScanOptionAllowDuplicatesKey, nil];
self.cbCM scanForPeripheralsWithServices:nil options:dic];

scanForPeripheralsWithServices方法

第一个参数为想要扫描指定uuid service的外围设备,nil是扫描所有。

第二个参数 扫描选项,

CBCentralManagerScanOptionAllowDuplicatesKey 当指定其为YES时,说明过滤功能是不启用的,也就是说centra每次都能接受到来自peripherals的广播包数据,这样的话对电池的寿命会有很大的影响。当设定为NO是每次寻找都会合并相同的peripheral。


/**

 *  发现外围设备

 *  @param central           中心管理

 *  @param peripheral        外围设备

 *  @param advertisementData 广播数据

 *  @param RSSI              信号质量(信号强度)

 */

- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI

测试参数peripheral中的name不能保证是最新的名字(当一个外围设备改变蓝牙名后),所以我们用广播中的数据

advertismentData,广播中的数据是最新的,可以通过广播蓝牙名和service 的uuid。


[self.cbCM stopScan];//停止扫描

连接外围设备

[self.cbCM connectPeripheral:device.peripheral
    options:[NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:CBConnectPeripheralOptionNotifyOnDisconnectionKey]];

options中可以设置一些连接设备的初始属性键值如下

NSString *const CBConnectPeripheralOptionNotifyOnConnectionKey;

APP被挂起时,这时如果APP连接到peripheral时,是否要给APP一个提示框,当然是在APP支持后台运行的前期下。

NSString *const CBConnectPeripheralOptionNotifyOnDisconnectionKey;

APP处于挂起状态时,恰好在这个时候断开连接,要不要给APP一个断开提示。这种情况只有指定了该APP指定在后台能够运行时才显示。

NSString *const CBConnectPeripheralOptionNotifyOnNotificationKey;

App处于挂起状态时,是否接受到所有的来自peripheral的包都要弹出提示框。当然这个key值也是以APP能够在后台运行为前期的。


//连接外围设备失败

- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error


// 连接到外围设备

- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral


发现服务、特征、描述

连接成功后,发现services

设置peripheral的delegate为self非常重要,否则,didDiscoverServices无法回调

peripheral.delegate = self;

[peripheral discoverServices:nil];参数指定service uuid,nil时则不限制uuid。
//已搜索到services

- (void) peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error
验证service uuid 是否是我们需要的uuid,如果正确则发现特征。

[peripheral discoverCharacteristics:nil forService:service];可以指定characteristic的uuid。
//已搜索到Characteristics

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

验证characteristic uuid是否正确,正确则发送数据,订阅特征。

通信

验证characteristic正确后,先订阅此characteristic
[peripheral setNotifyValue:YES forCharacteristic:c];这样就可以监听characteristic 值的改变了,改变时会回调下面方法:
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
然后发送数据给外围设备。
NSString *str = [NSString stringWithFormat:@"<%@>%@", (hasbond ? @"connect" : @"bind"), self.myUUID];
 NSData *data =[str dataUsingEncoding:NSUTF8StringEncoding];
[peripheral writeValue:data forCharacteristic:characteristic type:CBCharacteristicWriteWithResponse];
参数CBCharacteristicWriteWithResponse,则需要外围设备回应write请求。



你可能感兴趣的:(iOS开发)