iOS开发之蓝牙4.0 BLE开发

原文链接: http://zh.5long.me/2015/bluetooth-for-iOS-developer/

前言

物联网时代的到来,智能硬件层出不穷。蓝牙低功耗技术(BLE,Bluetooth Low Energy)使得蓝牙4.0的应用越来越广泛,比如小米手环就是使用蓝牙4.0来传输数据。

在蓝牙4.0之前,iOS的蓝牙功能作为私有,开发者只能使用蓝牙开发联机游戏而不能和第三方蓝牙设备通信,当时要开发一个用iPhone通过蓝牙来控制硬件的APP是件非常复杂的事情。好在蓝牙4.0之后,苹果开放了蓝牙4.0开发接口。而TI公司也推出了两款蓝牙芯片:CC2540和CC2541。之后就涌现了一大批基于蓝牙4.0的硬件设备和APP。如Stick-N-Find和耐克数字运动手环 NIKE+。随后中国也出现了一大批类似设备,小米、华为都出了手环。

本人差不多也是在那时接触蓝牙4.0,做一个蓝牙通信的APP。在当时资料还不是那么丰富的情况下,整个开发过程也是个探索过程。由于最近又需要做一个蓝牙通信的APP,于是整理了之前写的代码,重新写了一份蓝牙通信的代码(之前写的他太乱了 : D)。

本文介绍iOS下开发蓝牙4.0通信程序的流程以及使用到相关的库。

相关资料

关键类

蓝牙4.0相关的组件为CoreBluetooth,所以要使用之前先引用’CoreBluetooth/CoreBluetooth.h’,其中有两个重要的类:

  • ‘CBCentralManager’:蓝牙的控制中心,通过它来获知蓝牙状态、扫描周边蓝牙设备、发起连接等。
  • ‘CBPeripheral’:和周边蓝牙设备对应的一个对象,每一个蓝牙设备对应一个CBPeripheral对象。通过它乡对应的蓝牙设备发送数据、读取数据、获取RSSI值等。

‘CBCentralManager’和’CBPeripheral’通过协议来交互,对应的两个协议为:

  • ‘CBCentralManagerDelegate’:CBCentralManager’的协议。
  • ‘CBPeripheralDelegate’:CBPeripheral’的协议。

比如当’CBCentralManager’发起扫描周边设备时,当发现了一个设备后就会调用CBCentralManagerDelegate’的’- (void)centralManager:(CBCentralManager*)central didDiscoverPeripheral:(CBPeripheral*)peripheral advertisementData:(NSDictionary*)advertisementData RSSI:(NSNumber*)RSSI’,通过实现该方法就可做相应地处理。

关于协议,请参考iOS开发入门教程之Objective-C · 协议(Protocols)

以下列出这两个协议常用的方法:

CBCentralManagerDelegate

@required
/*
本机设备(iPhone/iPad)蓝牙状态改变
*/
- (void)centralManagerDidUpdateState:(CBCentralManager *)central;

@optional
/*
扫描到了一个蓝牙设备peripheral
*/
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI;

/*
成功连接蓝牙设备peripheral
*/
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral;

/*
连接蓝牙设备peripheral失败
*/
- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error;

/*
蓝牙设备peripheral已断开
*/
- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error;

CBPeripheralDelegate

@optional
/*
蓝牙设备peripheral的RSS值改变
*/
- (void)peripheralDidUpdateRSSI:(CBPeripheral *)peripheral error:(NSError *)error NS_DEPRECATED(NA, NA, 5_0, 8_0);

/*
从peripheral成功读取到services
*/
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error;

/*
从peripheral的service成功读取到characteristics
*/
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error;

/*
从蓝牙设备peripheral接收到数据
*/
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error;

/*
乡蓝牙设备peripheral成功写入数据,写数据时需要以CBCharacteristicWriteWithResponse才会调用
*/
 - (void)peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error;

蓝牙通信方式

蓝牙通信方式为service+characteristic,这和网络通信的IP+端口类似,service可理解为IP,characteristic可理解为端口号。servicecharacteristic都是一个数字编号,一般用16进制表示,如0xFFE00xFFE1

需要注意的是发送方和接收方必须是在相同的service+characteristic下才能正常发送和接收数据,如发送方在service0xFFE0characteristic0xFFE1下发送信息,接收方也应该在service0xFFE0characteristic0xFFE1下接收信息,否则是接收不到数据的。

一个蓝牙设备可以有多个service,一个service也可以有多个characteristic。不同的servicecharacteristic组合可形成多个通信通道。

还有一点需要提醒的是,由于苹果的限制,iOS SDK并没有提供获取蓝牙设备MAC地址的方法,所以一般还是不要用MAC,使用CBPeripheralUUIDname代替

蓝牙通信开发流程

在此就已经了解了iOS开发蓝牙通信所需要的库了,下面进入开发流程。蓝牙通信流程一般是:

  1. 初始化
  2. 扫描周边的蓝牙设备。
  3. 连接某一设备。
  4. 发送/接收数据。
  5. 断开连接

当然,所有这些操作都默认iPhone/iPad已开启蓝牙功能:D

初始化

初始化一个CBCentralManager

self.centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];

扫描周边的蓝牙设备

调用CBCentralManagerscanForPeripheralsWithServices就能扫描周边的设备。

[self.centralManager scanForPeripheralsWithServices:nil options:nil];

当扫描到一个蓝牙设备时,会调用CBCentralManagerDelegatecentralManager:(CBCentralManager *) didDiscoverPeripheral:(CBPeripheral *) advertisementData:(NSDictionary *) RSSI:(NSNumber *)方法,通过实现该协议方法,就可做相应地处理。

- (void)centralManager:(CBCentralManager*)central didDiscoverPeripheral:(CBPeripheral*)peripheral advertisementData:(NSDictionary*)advertisementData RSSI:(NSNumber*)RSSI
{
    NSLog(@"find new device:%@", peripheral.name);
}

连接某一设备

通过调用CBCentralManagerconnectPeripheral: options:方法就可向蓝牙设备发起连接,连接成功或失败会分别调用CBCentralManagerDelegatecentralManager:(CBCentralManager *) didConnectPeripheral:(CBPeripheral *)centralManager:(CBCentralManager *) didFailToConnectPeripheral:(CBPeripheral *) error:(NSError *)方法。

如果连接成功,还应该读取peripheralservicecharacteristic

[self.centralManager connectPeripheral:peripheral options:nil];

- (void)centralManager:(CBCentralManager*)central didConnectPeripheral:(CBPeripheral*)peripheral
{
    peripheral.delegate = self;
    [peripheral discoverServices:nil];
}

- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error
{
    [peripheral discoverCharacteristics:nil forService:service];
}

发送数据

发送数据只需要在指定的servicecharacteristic组合下发送即可,如果是以CBCharacteristicWriteWithResponse模式发送,发送完后还会调用CBPeripheralDelegateperipheral:(CBPeripheral *) didWriteValueForCharacteristic:(CBCharacteristic *) error:(NSError *),实现该协议方法可判断发送是否成功。以CBCharacteristicWriteWithoutResponse模式则不会有回调。

[peripheral writeValue:data forCharacteristic:characteristic type:CBCharacteristicWriteWithResponse];

- (void)peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
{
    if (error)
    {
        NSLog(@"%@", error);
    }
}

接收数据

当接收到数据后,CBCentralManager会调用协议CBCentralManagerDelegateperipheral:(CBPeripheral *) didUpdateValueForCharacteristic:(CBCharacteristic *) error:(NSError *)error方法,实现该方法就可获取接收到得数据。

- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
{
    NSString *msg=[[NSString alloc] initWithData:characteristic.value  encoding:NSUTF8StringEncoding];
    NSLog(@"message:%@", msg);
}

断开连接

通过调用CBCentralManagercancelPeripheralConnection:即可断开蓝牙连接,成功断开后,会调用CBCentralManagerDelegate- (void)centralManager:(CBCentralManager *) didDisconnectPeripheral:(CBPeripheral *) error:(NSError *)方法。

[self.centralManager cancelPeripheralConnection:peripheral];

- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error
{
}

结语

本文介绍了开发iOS下蓝牙通信APP的必要知识及开发流程,给出了一个iOS蓝牙通信的框架。关于各个函数的详细说明,还需要查阅官方文档。结合官方文档,相信读者可以开发出一个蓝牙通信的模型来。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值