转载自:www.cocoachina.com/ios/20151105/14071.html

                          原作者:刘彦玮

再上一节说了app作为central连接peripheral的情况,这一节介绍如何使用app发布一个peripheral,给其他的central连接

还是这张图,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

准备环境

1 Xcode

2 开发证书和手机(蓝牙程序需要使用使用真机调试,使用模拟器也可以调试,但是方法很蛋疼,我会放在最后说),如果不行可以使用osx程序调试

3 蓝牙外设

实现步骤

1. 打开peripheralManager,设置peripheralManager的委托

设置当前ViewController实现CBPeripheralManagerDelegate委托

    @interface BePeripheralViewController : UIViewController

初始化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];
    }
}

代码下载:

我博客中大部分示例代码都上传到了github,地址是:https://github.com/coolnameismy/demo,点击跳转代码下载地址

本文代码存放目录是BleDemo

如果大家支持,请follow我的github账号,并star我的项目,有其他问题可以在blog中给我留言 blog的RSS订阅

iOS 蓝牙开发(三)app作为外设被连接的实现(转)的更多相关文章

  1. iOS蓝牙开发(二)蓝牙相关基础知识

    原文链接: http://liuyanwei.jumppo.com/2015/07/17/ios-BLE-1.html iOS蓝牙开发(一)蓝牙相关基础知识: 蓝牙常见名称和缩写 MFI ====== ...

  2. iOS 蓝牙开发资料记录

    一.蓝牙基础认识:   1.iOS蓝牙开发:  iOS蓝牙开发:蓝牙连接和数据读写   iOS蓝牙后台运行  iOS关于app连接已配对设备的问题(ancs协议的锅)          iOS蓝牙空中 ...

  3. iOS蓝牙开发(一)蓝牙相关基础知识(转)

    转载自:http://www.cocoachina.com/ios/20150915/13454.html 原文作者:刘彦玮 蓝牙常见名称和缩写 MFI ======= make for ipad , ...

  4. iOS蓝牙开发

    蓝牙常见名称和缩写 MFI ======= make for ipad ,iphone, itouch 专们为苹果设备制作的设备 BLE ==== buletouch low energy,蓝牙4.0 ...

  5. iOS蓝牙开发(4.0)详解

    最近由于项目需要, 一直在研究蓝牙4.0,在这儿分享给大家, 望共同进步. 一.关于蓝牙开发的一些重要的理论概念: 1.当前ios中开发蓝牙所运用的系统库是<CoreBluetooth/Core ...

  6. iOS 蓝牙开发详解

    目前iOS智能硬件的开发交互方式主要分为两种,一种是基于低功耗的蓝牙4.0技术(由于耗电低,也称作为BLE(Bluetooth Low Energy))对应iOS的框架为CoreBluetooth,另 ...

  7. iOS蓝牙开发CoreBluetooth快速入门

    在iOS开发中,实现蓝牙通信有两种方式,一种是使用传统的GameKit.framework,另一种就是使用在iOS 5中加入的CoreBluetooth.framework. 利用CoreBlueto ...

  8. ios蓝牙开发(一)蓝牙相关基础知识

    蓝牙常见名称和缩写 MFI ======= make for ipad ,iphone, itouch 专们为苹果设备制作的设备 BLE ==== buletouch low energy,蓝牙4.0 ...

  9. iOS 蓝牙开发(四)BabyBluetooth蓝牙库介绍(转)

    转载自:http://www.cocoachina.com/ios/20151106/14072.html 原文作者:刘彦玮 BabyBluetooth 是一个最简单易用的蓝牙库,基于CoreBlue ...

  10. ios蓝牙开发(四)BabyBluetooth蓝牙库

    BabyBluetooth 是一个最简单易用的蓝牙库,基于CoreBluetooth的封装,并兼容ios和mac osx. 特色: 基于原生CoreBluetooth框架封装的轻量级的开源库,可以帮你 ...

随机推荐

  1. Android屏幕禁止休眠的方法

    实现这一功能的方法有两种,一种是在Manifest.xml文件里面声明,一种是在代码里面修改LayoutParams的标志位.具体如下: 1.在Manifest.xml文件里面用user-permis ...

  2. JavaScript String 对象

    JavaScript String 对象 String 对象 String 对象用于处理文本(字符串). String 对象创建方法: new String(). 语法 var txt = new S ...

  3. angular的uiRouter服务学习(5) --- $state.includes()方法

    $state.includes方法用于判断当前激活状态是否是指定的状态或者是指定状态的子状态. $state.includes(stateOrName,params,options) $state.i ...

  4. hadoop资料收集

    大数据时代——为什么用hadoop hadoop应用场景 Hadoop一般用在哪些业务场景? Hadoop虽然强大,但不是万能的

  5. 解决Ehcache缓存警告问题

    警告: Creating a new instance of CacheManager using the diskStorePath "D:\Apache Tomcat 6.0.18\te ...

  6. C#.NET 大型通用信息化系统集成快速开发平台 4.0 版本 - 多系统开发接口 - 苹果客户端开发接口

    最近工作上需要,给苹果客户端开发接口,实现集中统一的用户管理,下面是接口调用参考. 1: 获取OpenId? http://127.0.0.1/GetOpenId.ashx?username=Admi ...

  7. Linux socket多进程服务器框架二

    客户端未解决Bug:子进程或者父进程退出的时候,我无法做到两个进程都调用clt_socket_Destory()方式释放socket句柄, 但是进程退出后,相应的资源也会释放,有一定影响,但是不大,以 ...

  8. kindeditor编辑器里面 filterMode为false时候,允许输入任何代码

    kindeditor编辑器里面 filterMode为false时候,允许输入任何代码

  9. 系统升级日记(4):如何快速的修改Infopath中的各种URL

    摘要: 最近一段时间在公司忙于将各类系统进行升级,其最主要的目标有两个,一个是将TFS2010升级到TFS2013,另外一个是将SharePoint 2010升级到SharePoint 2013.本记 ...

  10. sql 几点记录

      1       With子句 1.1     学习目标 掌握with子句用法,并且了解with子句能够提高查询效率的原因. 1.2     With子句要点 with子句的返回结果存到用户的临时表 ...