再上一节说了 App 作为 central 连接 peripheral 的情况, 这一节介绍如何使用 App 发布一个 peripheral, 给其他的 central 连接
image
还是这张图, central 模式用的都是左边的类, 而 peripheral 模式用的是右边的类
peripheral 模式的流程
1\. 打开 peripheralManager, 设置 peripheralManager 的委托
2\. 创建 characteristics,characteristics 的 description 创建 service, 把 characteristics 添加到 service 中, 再把 service 添加到 peripheralManager 中
3\. 开启广播 advertising
4\. 对 central 的操作进行响应
- 4.1 读 characteristics 请求
- 4.2 写 characteristics 请求
- 4.4 订阅和取消订阅 characteristics
准备环境
xcode
开发证书和手机 (蓝牙程序需要使用使用真机调试, 使用模拟器也可以调试, 但是方法很蛋疼, 我会放在最后说), 如果不行可以使用 OS X 程序调试
蓝牙外设
实现步骤
1. 打开 peripheralManager, 设置 peripheralManager 的委托
设置当前 ViewController 实现 CBPeripheralManagerDelegate 委托
@interface BePeripheralViewController : UIViewController<CBPeripheralManagerDelegate>
初始化 peripheralManager
- /*
- 和 CBCentralManager 类似, 蓝牙设备打开需要一定时间, 打开成功后会进入委托方法
- - (void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral;
- 模拟器永远也不会得 CBPeripheralManagerStatePoweredOn 状态
- */
- peripheralManager = [[CBPeripheralManager alloc]initWithDelegate:self queue:nil];
2. 创建 characteristics,characteristics 的 description , 创建 service, 把 characteristics 添加到 service 中, 再把 service 添加到 peripheralManager 中
在委托方法 - (void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral 中, 当 peripheral 成功打开后, 才可以配置 service 和 characteristics. 这里创建的 service 和 chara 对象是 CBMutableCharacteristic 和 CBMutableService. 他们的区别就像 NSArray 和 NSMutableArray 区别类似. 我们先创建 characteristics 和 description,description 是 characteristics 的描述, 描述分很多种, 这里不细说了, 常用的就是 CBUUIDCharacteristicUserDescriptionString.
- //peripheralManager 状态改变
- - (void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral{
- switch (peripheral.state) {
- // 在这里判断蓝牙设别的状态 当开启了则可调用 setUp 方法 (自定义)
- case CBPeripheralManagerStatePoweredOn:
- NSLog(@"powered on");
- [info setText:[NSString stringWithFormat:@"设备名 %@已经打开, 可以使用 center 进行连接",LocalNameKey]];
- [self setUp];
- break;
- case CBPeripheralManagerStatePoweredOff:
- NSLog(@"powered off");
- [info setText:@"powered off"];
- break;
- default:
- break;
- }
- }
- // 配置 bluetooch 的
- -(void)setUp{
- //characteristics 字段描述
- CBUUID *CBUUIDCharacteristicUserDescriptionStringUUID = [CBUUID UUIDWithString:CBUUIDCharacteristicUserDescriptionString];
- /*
- 可以通知的 Characteristic
- properties:CBCharacteristicPropertyNotify
- permissions CBAttributePermissionsReadable
- */
- CBMutableCharacteristic *notiyCharacteristic = [[CBMutableCharacteristic alloc]initWithType:[CBUUID UUIDWithString:notiyCharacteristicUUID] properties:CBCharacteristicPropertyNotify value:nil permissions:CBAttributePermissionsReadable];
- /*
- 可读写的 characteristics
- properties:CBCharacteristicPropertyWrite | CBCharacteristicPropertyRead
- permissions CBAttributePermissionsReadable | CBAttributePermissionsWriteable
- */
- CBMutableCharacteristic *readwriteCharacteristic = [[CBMutableCharacteristic alloc]initWithType:[CBUUID UUIDWithString:readwriteCharacteristicUUID] properties:CBCharacteristicPropertyWrite | CBCharacteristicPropertyRead value:nil permissions:CBAttributePermissionsReadable | CBAttributePermissionsWriteable];
- // 设置 description
- CBMutableDescriptor *readwriteCharacteristicDescription1 = [[CBMutableDescriptor alloc]initWithType: CBUUIDCharacteristicUserDescriptionStringUUID value:@"name"];
- [readwriteCharacteristic setDescriptors:@[readwriteCharacteristicDescription1]];
- /*
- 只读的 Characteristic
- properties:CBCharacteristicPropertyRead
- permissions CBAttributePermissionsReadable
- */
- CBMutableCharacteristic *readCharacteristic = [[CBMutableCharacteristic alloc]initWithType:[CBUUID UUIDWithString:readCharacteristicUUID] properties:CBCharacteristicPropertyRead value:nil permissions:CBAttributePermissionsReadable];
- //service1 初始化并加入两个 characteristics
- CBMutableService *service1 = [[CBMutableService alloc]initWithType:[CBUUID UUIDWithString:ServiceUUID1] primary:YES];
- [service1 setCharacteristics:@[notiyCharacteristic,readwriteCharacteristic]];
- //service2 初始化并加入一个 characteristics
- CBMutableService *service2 = [[CBMutableService alloc]initWithType:[CBUUID UUIDWithString:ServiceUUID2] primary:YES];
- [service2 setCharacteristics:@[readCharacteristic]];
- // 添加后就会调用代理的 - (void)peripheralManager:(CBPeripheralManager *)peripheral didAddService:(CBService *)service error:(NSError *)error
- [peripheralManager addService:service1];
- [peripheralManager addService:service2];
- }
3. 开启广播 advertising
- //perihpheral 添加了 service
- - (void)peripheralManager:(CBPeripheralManager *)peripheral didAddService:(CBService *)service error:(NSError *)error{
- if (error == nil) {
- serviceNum++;
- }
- // 因为我们添加了 2 个服务, 所以想两次都添加完成后才去发送广播
- if (serviceNum==2) {
- // 添加服务后可以在此向外界发出通告 调用完这个方法后会调用代理的
- //(void)peripheralManagerDidStartAdvertising:(CBPeripheralManager *)peripheral error:(NSError *)error
- [peripheralManager startAdvertising:@{
- CBAdvertisementDataServiceUUIDsKey : @[[CBUUID UUIDWithString:ServiceUUID1],[CBUUID UUIDWithString:ServiceUUID2]],
- CBAdvertisementDataLocalNameKey : LocalNameKey
- }
- ];
- }
- }
- //peripheral 开始发送 advertising
- - (void)peripheralManagerDidStartAdvertising:(CBPeripheralManager *)peripheral error:(NSError *)error{
- NSLog(@"in peripheralManagerDidStartAdvertisiong");
- }
4. 对 central 的操作进行响应
- 4.1 读 characteristics 请求
- 4.2 写 characteristics 请求
- 4.3 订阅和取消订阅 characteristics
- // 订阅 characteristics
- -(void)peripheralManager:(CBPeripheralManager *)peripheral central:(CBCentral *)central didSubscribeToCharacteristic:(CBCharacteristic *)characteristic{
- NSLog(@"订阅了 %@的数据",characteristic.UUID);
- // 每秒执行一次给主设备发送一个当前时间的秒数
- timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(sendData:) userInfo:characteristic repeats:YES];
- }
- // 取消订阅 characteristics
- -(void)peripheralManager:(CBPeripheralManager *)peripheral central:(CBCentral *)central didUnsubscribeFromCharacteristic:(CBCharacteristic *)characteristic{
- NSLog(@"取消订阅 %@的数据",characteristic.UUID);
- // 取消回应
- [timer invalidate];
- }
- // 发送数据, 发送当前时间的秒数
- -(BOOL)sendData:(NSTimer *)t {
- CBMutableCharacteristic *characteristic = t.userInfo;
- NSDateFormatter *dft = [[NSDateFormatter alloc]init];
- [dft setDateFormat:@"ss"];
- NSLog(@"%@",[dft stringFromDate:[NSDate date]]);
- // 执行回应 Central 通知数据
- return [peripheralManager updateValue:[[dft stringFromDate:[NSDate date]] dataUsingEncoding:NSUTF8StringEncoding] forCharacteristic:(CBMutableCharacteristic *)characteristic onSubscribedCentrals:nil];
- }
- // 读 characteristics 请求
- - (void)peripheralManager:(CBPeripheralManager *)peripheral didReceiveReadRequest:(CBATTRequest *)request{
- NSLog(@"didReceiveReadRequest");
- // 判断是否有读数据的权限
- if (request.characteristic.properties & CBCharacteristicPropertyRead) {
- NSData *data = request.characteristic.value;
- [request setValue:data];
- // 对请求作出成功响应
- [peripheralManager respondToRequest:request withResult:CBATTErrorSuccess];
- }else{
- [peripheralManager respondToRequest:request withResult:CBATTErrorWriteNotPermitted];
- }
- }
- // 写 characteristics 请求
- - (void)peripheralManager:(CBPeripheralManager *)peripheral didReceiveWriteRequests:(NSArray *)requests{
- NSLog(@"didReceiveWriteRequests");
- CBATTRequest *request = requests[0];
- // 判断是否有写数据的权限
- if (request.characteristic.properties & CBCharacteristicPropertyWrite) {
- // 需要转换成 CBMutableCharacteristic 对象才能进行写值
- CBMutableCharacteristic *c =(CBMutableCharacteristic *)request.characteristic;
- c.value = request.value;
- [peripheralManager respondToRequest:request withResult:CBATTErrorSuccess];
- }else{
- [peripheralManager respondToRequest:request withResult:CBATTErrorWriteNotPermitted];
- }
- }
如果你依然在编程的世界里迷茫, 不知道自己的未来规划, 小编给大家推荐一个 iOS 高级交流群: 458839238 里面可以与大神一起交流并走出迷茫. 小白可进群免费领取学习资料, 看看前辈们是如何在编程的世界里傲然前行!
群内提供数据结构与算法, 底层进阶, swift, 逆向, 整合面试题等免费资料
附上一份收集的各大厂面试题 (附答案) ! 群文件直接获取
各大厂面试题
image
来源: http://www.jianshu.com/p/2cb6205a5222