iOS使用BLE实现简单的周边设备广告

本文在iOS7中实现了简单的周边设备(Peripheral)发送广告(Advertising)功能。

这部分源代码见:https://github.com/MarshalW/BleDemo/tree/m2

运行这部分代码,然后可使用第三方工具检测到这个发送广告的周边设备。

这是iOS LightBlue的截图:

或者,Android BLE Scanner的截图:

在xcode日志中可看到类似这样的日志:

1
2
3
2013-12-23 19:17:49.716 BleDemo[2173:60b] >>>设备支持BLE
2013-12-23 19:17:49.725 BleDemo[2173:60b] >>>开始发送advertising
2013-12-23 19:17:49.730 BleDemo[2173:60b] >>>发送advertising成功

创建支持BLE的项目

xcode创建一个Single View Application,然后,需要在该项目的Build Phases中Link Binary With Libraries加入CoreBluetooth.framwork的支持。

在需要引用CoreBluetooth的代码前加入import:

1
#import <CoreBluetooth/CoreBluetooth.h>

编写代码的方法、步骤和解释

这个示例只需实现周边设备(Peripheral)角色即可,中央设备(Central)使用了2个第三方工具来做测试:

  • LightBlue,iOS app,可在App Store免费下载
  • BLE Scanner,Android app,可在Google play上免费下载

实现实现周边设备(Peripheral)简要步骤是:

  1. 让ViewController实现CBPeripheralManagerDelegate,CB表示CoreBluetooth框架,PeripheralManager就是周边设备对象

  2. 实现CBPeripheralManagerDelegate的三个方法

    1. peripheralManagerDidUpdateState,检查蓝牙状态,可能未开蓝牙或者蓝牙不支持BLE(iPhone4s已下设备)
    2. didAddService,发送广告(advertising)
    3. peripheralManagerDidStartAdvertising,发送广告后,如果没有错误就是成功了
  3. 创建PeripheralManager对象等

实现CBPeripheralManagerDelegate

ViewController加入:

1
@interface ViewController () <CBPeripheralManagerDelegate>

实现CBPeripheralManagerDelegate的三个方法

第一个被执行的是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

- (void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral
{
CBUUID *serviceUUID =nil;

switch (peripheral.state) {

case CBPeripheralManagerStatePoweredOn:
NSLog(@">>>设备支持BLE");

serviceUUID=[CBUUID UUIDWithString:kServiceUUID];
self.service=[[CBMutableService alloc] initWithType:serviceUUID
primary:YES];
[self.peripheralManger addService:self.service];

break;
default:
NSLog(@">>>设备不支持BLE或者是未打开蓝牙");
break;
}
}

如果未开启蓝牙,iOS系统会自动提示,并可点击按钮跳转到设置。

第二个被执行的是:

1
2
3
4
5
6
7

- (void)peripheralManager:(CBPeripheralManager *)peripheral didAddService:(CBService *)service error:(NSError *)error {
if (error == nil) {
[self.peripheralManger startAdvertising:@{ CBAdvertisementDataLocalNameKey : @"MarshalServer", CBAdvertisementDataServiceUUIDsKey : @[[CBUUID UUIDWithString:kServiceUUID]] }];
NSLog(@">>>开始发送advertising");
}
}

如果蓝牙状态没有问题,就是没有error,则开始发送advertising。这里为Peripheral设置了个local name,另外,还有个UUID,后面会说明怎么创建的。

第三个被执行的是:

1
2
3
4
5
6
7

- (void)peripheralManagerDidStartAdvertising:(CBPeripheralManager *)peripheral error:(NSError *)error
{
if(error==nil){
NSLog(@">>>发送advertising成功");
}
}

如果第二步成功,就会调用这个方法,如果没有错误,就说明advertising发送成功了。

创建Peripheral对象等

创建成员变量:

1
@property (strong, nonatomic) CBPeripheralManager *peripheralManger;

然后在viewDidLoad中创建这个对象:

1
self.peripheralManger=[[CBPeripheralManager alloc] initWithDelegate:self queue:nil];

另外,创建了一个UUID,用于标识Peripheral:

1
static NSString * const kServiceUUID = @"DF3AAF91-0BB3-4C81-B7CE-CFC8BEB3ECCA";

这个UUID,可在Mac下命令行生成,比如:

1
$ uuidgen
A05E68FD-76C2-414B-BC9D-4C48DE30CAD5