iOS的蓝牙开发相关Apple大致有以下几种方式。
1 GameKit.framework
【只能存在于iOS设备之间,多用于游戏
能搜索到的demo比较多,不确切说名字了,code4app里面就有】
2 CoreBlueTooth.framework
【必须要支持蓝牙4.0,且iPhone4以上,即至少4s手机。可与第三方设备交互数据,
官方demo是Temperature Sensor 】
心得:吃透扫描,连接,断开,数据交互等技术点,掌握central和perphiral的交互接口(delegate)
3 ExternalAccessory.framework
【可于第三方蓝牙设备交互,但是蓝牙设备必须经过MFI认证,需要有苹果的协议,
官方demo是 EADemo和 BTLE】
4 Multipeer Connectivity.framework
【只能用于iOS设备之间,且iOS7才引入。主要是为了共享文件,但是文件是在sandbox内
官方demo是ios7 sample】
由于我是做的接入第三方蓝牙设备的,故只能采取2 还 3 方式。
但又由于3方式需要经过苹果公司的MFI认证,而国内很多蓝牙提供商事没有经过这个认证的所以我们采用了第二种方式。CoreBlueTooth,也就是通过蓝牙4.0的 BLE模式来进行开发。
下面详细介绍一下BLE开发模式在iOS下的应用方式。
首先BLE将蓝牙设备分为了两类:
一 中央设备(Central)
二 外围设备(Peripheral)
这两个设备的交互方式如下:
首先外围设备会广播自身的信息,这时中央设备如果启用检索发现功能,就会发现广播的外围设备并得到这些外围设备的列表。
中央设备选择你需要连接的外围设备连接上。这时中央设备和外围设备交互的第一步就被打通了。
详细分析接下来的步骤如下图:
左侧为中央设备(Central),右侧为外围设备(Peripheral) 。
这里我以Central连接Peripheral,并向Peripheral发送数据为例,结合代码进行分析。
下面具体介绍使用CoreBluetooth.framework的代码步骤:
//蓝牙系统库
#import <CoreBluetooth/CoreBluetooth.h>
//必须要由UUID来唯一标示对应的service和characteristic
#define kServiceUUID @"5C476471-1109-4EBE-A826-45B4F9D74FB9"
#define kCharacteristicHeartRateUUID @"82C7AC0F-6113-4EC9-92D1-5EEF44571398"
#define kCharacteristicBodyLocationUUID @"537B5FD6-1889-4041-9C35-F6949D1CA034"
@interface ViewController ()<CBCentralManagerDelegate,CBPeripheralDelegate>
@property (nonatomic,strong)CBCentralManager * centralManager;
@property (nonatomic,strong)CBPeripheral * peripheral;
@end
1.创建中心角色
#import <CoreBluetooth/CoreBluetooth.h>
- (void)viewDidLoad
{
[super viewDidLoad];
//初始化蓝牙 central manager
_centralManager = [[CBCentralManager alloc]initWithDelegate:self queue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) options:nil];
}
2.扫描外设
[
_centralManager
scanForPeripheralsWithServices:nil options:@{CBCentralManagerRestoredStateScanOptionsKey:@(YES)}];
3.连接外设
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI
{
[self connect:peripheral];
}
-(BOOL)connect:(CBPeripheral *)peripheral{
self.centralManager.delegate = self;
[self.centralManager
.manager connectPeripheral:peripheral
options:[NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:CBConnectPeripheralOptionNotifyOnDisconnectionKey]];
}
4.扫描外设中的服务和特征
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral
{
NSLog(@"Did connect to peripheral: %@", peripheral);
_peripheral
= peripheral;
[peripheral setDelegate:self]; //查找服务 [peripheral discoverServices:nil]; }
发现服务:
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error
{
NSLog(@"didDiscoverServices");
for (CBService *service in peripheral.services)
{
//发现服务
NSLog(@"Service found with UUID: %@", service.UUID); <br>//查找特征
[peripheral discoverCharacteristics:nil forService:service];
break;
}
}
发现服务中的特征:
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error
{
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.与外设进行数据交互
读取数据:
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
{
// NSLog(@"收到的数据:%@",characteristic.value);
[self decodeData:characteristic.value];
}
写数据:
NSData *d2 = [[PBABluetoothDecode sharedManager] HexStringToNSData:@"0x02"];
[self.peripheral writeValue:d2 forCharacteristic:characteristic type:CBCharacteristicWriteWithoutResponse];