说明:苹果官方开发文档中涉及一些名词:Central(中心设备)、Peripheral(外围设备)、advertising(广告)、Services(服务)、Characteristic(特征)等,请点击查看我的另一篇翻译

目录:

步骤1.建立一个Central Manager实例进行蓝牙管理

步骤2.搜索外围设备

步骤3.连接外围设备

步骤4.获得外围设备的服务

步骤5.获得服务的特征

步奏6.从外围设备读数据(直接读取和订阅两种方法)

步骤7.给外围设备发送数据

步骤一.开启Central Manager

CBCentralManager 是Core Bluetooth的一个对象,代表一个本地中心设备,在使用任何蓝牙传输前,你必须给CBCentralManager实例分配内存和初始化。可以通过CBCentralManager类的initWithDelegate:queue:options: 方法:

myCentralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil options:nil];

在这个例子中,self会被设置为接收所有中心设备角色的事件的代理,设置dispatch queue为nil后,central manager会通过主线程来处理这些事件。ViewController需要实现CBCentralManagerDelegate,CBPeripheralDelegate这两个代理

当创建了一个central manager,会回调代理的centralManagerDidUpdateState:方法,你必须实现这个代理方法来确定中心设备是否支持BLE以及是否可用。

步骤二.搜索正在广告的外围设备

中心设备的第一个任务是搜索你的APP可以连接的外围设备,正如上一篇文章中提到的,广告(advertising)是外围设备使其被周围设备发现的主要方法,你可以通过CBCentralManager类的scanForPeripheralsWithServices:options: 方法,搜索任何正在广告的外围设备:

[myCentralManager scanForPeripheralsWithServices:nil options:nil];

你调用了scanForPeripheralsWithServices:options: 方法来搜索可连接的外围设备后,central manager 在每次搜索到一个外围设备都会回调其代理的centralManager:didDiscoverPeripheral:advertisementData:RSSI: 方法。任何被搜索到的外围设备都以CBPeripheral类的方式返回。像下面的代码,你可以实现这个代理方法来罗列出所有被搜索到的蓝牙设备:

- (void)centralManager:(CBCentralManager *)centraldidDiscoverPeripheral:(CBPeripheral *)peripheraladvertisementData:(NSDictionary *)advertisementDataRSSI:(NSNumber *)RSSI {NSLog(@"Discovered %@", peripheral.name);...

当你已经找到了一个你需要连接的外围设备,停止搜索其它设备来节省电量。

[myCentralManager stopScan];
NSLog(@"Scanning stopped”);

步骤三.连接一个你搜索到并希望连接的外围设备

在你搜索到一个外围设备,并且它广告了你需要的服务,你可以请求和这个外围设备连接,通过调用 CBCentralManager类的connectPeripheral:options:方法,简而言之,调用这个方法并且说明你需要连接的外围设备:

 [myCentralManager connectPeripheral:peripheral options:nil];

假设连接成功了,central manager 会回调其代理方法centralManager:didConnectPeripheral: ,你可以实现这个方法来打印“外围设备连接”:

- (void)centralManager:(CBCentralManager *)centraldidConnectPeripheral:(CBPeripheral *)peripheral {NSLog(@"Peripheral connected");...
</pre><p></p><p style=""></p><p style="">在你开始和外围设备交互之前,你应该设置外围设备的代理以确保它能接收合适的回调,像这样</p><div><pre name="code" class="objc" style="color: rgb(102, 102, 102);">peripheral.delegate = self;

步骤四.搜索你已经连接的外围设备的服务

在你与外围设备建立连接之后,你可以开始勘察它的数据。第一步是勘察外围设备提供了什么服务,因为外围设备广告的数据有大小限制,你或许会发现外围设备提供比它广告的还有更多服务。你可以通过CBPeripheral类的discoverServices: 方法来发现一个外围设备提供的所有服务:

 [peripheral discoverServices:nil];

当发现了具体的服务,外围设备(已经连接的 CBPeripheral类)会回调其代理的peripheral:didDiscoverServices: 方法。Core Bluetooth 建立CBService 类的array数组——存储外围设备的每一个服务。像下面的代码,你可以实现这个代理方法来获得发现的服务列表:

- (void)peripheral:(CBPeripheral *)peripheraldidDiscoverServices:(NSError *)error {for (CBService *service in peripheral.services) {NSLog(@"Discovered service %@", service);...}…

步骤五.搜索服务的特征

假定你已经找到了你需要的服务,下一步就是探索服务的所有“特征”(characteristics),搜索一个服务的所有特征只要调用 CBPeripheral类的discoverCharacteristics:forService:方法,参数为具体的服务:

    NSLog(@"Discovering characteristics for service %@", interestingService);[peripheral discoverCharacteristics:nil forService:interestingService];

当发现了指定服务的特征,外围设备会回调peripheral:didDiscoverCharacteristicsForService:error:代理方法。Core Bluetooth建立存储CBCharacteristic实例的array数组———每一个都代表一个发现了的特征。下面的示例就是实现这个代理方法来简单地打印每个发现了的特征:

- (void)peripheral:(CBPeripheral *)peripheraldidDiscoverCharacteristicsForService:(CBService *)serviceerror:(NSError *)error {for (CBCharacteristic *characteristic in service.characteristics) {NSLog(@"Discovered characteristic %@", characteristic);...}...

步骤六.取得特征的值(就是从外围设备取数据)

一个特征包含一个代表外围设备服务的简单值,例如,有一个健康温度计服务,这个服务有一个温度测量特征,而这个特征有一个摄氏温度的值,你可以直接读取或者订阅这个特征来取得这个特征对应的值。

6.1直接读取特征的值

你得到你希望得到的服务的某个特征后,你可以通过调用CBPeripheral类的readValueForCharacteristic:方法来读取这个特征对应的值,参数为需要读取的特征:

  NSLog(@"Reading value for characteristic %@", interestingCharacteristic);[peripheral readValueForCharacteristic:interestingCharacteristic];

当你试图去读一个特征对应的值,外围设备会回调它的代理方法

peripheral:didUpdateValueForCharacteristic:error:去取值,如果值成功返回,你可以通过特征的value属性来获得它:

- (void)peripheral:(CBPeripheral *)peripheraldidUpdateValueForCharacteristic:(CBCharacteristic *)characteristicerror:(NSError *)error {NSData *data = characteristic.value;// parse the data as needed...

6.2订阅一个特征的值

在某些使用情况下,通过 readValueForCharacteristic: 读取一个特征的值会很有效率,但是这不是获得值改变的最有效率方法,对于大部分特征值的改变——例如,你在给定时间的心率,你应该通过订阅来获得它。当你订阅了一个特征的值,你可以在值改变的时候接收到通知。你可以通过CBPeripheral类的setNotifyValue:forCharacteristic: 方法来订阅你需要的特征,参数为YES,以及需要订阅的特征:

[peripheral setNotifyValue:YES forCharacteristic:interestingCharacteristic];

当你试图去订阅(或取消订阅)一个特征时,外围设备会调用 它的代理的peripheral:didUpdateNotificationStateForCharacteristic:error:方法,如果订阅请求失败,你可以通过实现这个方法来获得错误原因:

- (void)peripheral:(CBPeripheral *)peripheraldidUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristicerror:(NSError *)error {if (error) {NSLog(@"Error changing notification state: %@",[error localizedDescription]);}...

当你成功订阅了某个特征,在特征的值改变时,外围设备会通知你的app,每次值改变,外围设备会调用 其代理的peripheral:didUpdateValueForCharacteristic:error:方法。你可以通过实现这个方法来获得改变的值,这个方法和上面直接读取时回调的方法一样。

步骤七.写值到特征中(就是发数据给外围设备)

在某些使用情况下,需要写数据到特征中,这是可行的。例如,你的app与一个BLE电子温度调节器交互,你或许需要提供给调节器一个值来设定房间的温度,如果特征的值可以被写,你可以通过CBPeripheral类的writeValue:forCharacteristic:type:方法把数据(NSData的实例)写到特征的值里:

NSLog(@"Writing value for characteristic %@", interestingCharacteristic);[peripheral writeValue:dataToWrite forCharacteristic:interestingCharacteristictype:CBCharacteristicWriteWithResponse];

当你试图去写特征的值时,你需要说明你需要用哪种类型的写的方法。上面的例子中,写的方法为CBCharacteristicWriteWithResponse,用这个方法,外围设备会让你的app知道写操作是否成功(就是)。更多写的方法请看CBPeripheral Class Reference里面的CBCharacteristicWriteType枚举。

使用CBCharacteristicWriteWithResponse方法给外围设备写数据时,会回调 其代理的peripheral:didWriteValueForCharacteristic:error:方法。如果写数据失败,可以通过这个方法找到失败的原因。像这样:

- (void)peripheral:(CBPeripheral *)peripheraldidWriteValueForCharacteristic:(CBCharacteristic *)characteristicerror:(NSError *)error {if (error) {NSLog(@"Error writing characteristic value: %@",[error localizedDescription]);}...

简单写了个测试demo,见下图,输入框为待发送的文本,Label为接收到的文本,我的蓝牙测试模块是返回我发送的数据。

这个demo只连接指定蓝牙名字的蓝牙设备,测试时,请将第十行的HMSoft改为自己的外围设备名称,这个demo比较水,每次viewdidload后就去搜索蓝牙设备并连接,不便于测试,自己可以加断点调试。

另外由于我的测试的蓝牙设备不支持CBCharacteristicWriteWithResponse,发送数据时都返回没有权限的错误,所以我用的CBCharacteristicWriteWithoutResponse。成功后不会回调didWriteValueForCharacteristic方法

下载demo :https://github.com/dolacmeng/Bluetooth

【iOS官方文档翻译】iOS的蓝牙连接、数据接收及发送相关推荐

  1. iOS的蓝牙连接 数据接收及发送

    说明:苹果官方开发文档中涉及一些名词:Central(中心设备).Peripheral(外围设备).advertising(广告).Services(服务).Characteristic(特征)等,我 ...

  2. 【iOS官方文档翻译】iOS蓝牙的基本概念

    之前写了[iOS官方文档翻译]iOS的蓝牙连接.数据接收及发送一文,介绍了怎样进行蓝牙通讯,但是很多基本概念没有进行解释,看起来可能有点吃力,所以现在再翻译一篇苹果对官方蓝牙4.0一些基本概念介绍的文 ...

  3. About HTTP Live Streaming官方文档翻译 [iOS]

    新博客地址:About HTTP Live Streaming官方文档翻译 [iOS] 版权声明:本文为博主原创翻译,如需转载请注明出处. 苹果源文档地址 - 点击这里 About HTTP Live ...

  4. iOS 官方文档翻译

    各路大神爱发博客的.爱写写东西的.爱分享的.爱技术的.潮人.妹纸.男神.都可已加入到我们这个大家庭来.一起做些有趣的事情.iOS 官方文档翻译QQ群:486111671.github 地址:https ...

  5. 一分钟读懂低功耗蓝牙连接数据包

    一分钟读懂低功耗蓝牙(BLE)连接数据包 1.概述    BLE 连接过程中有三个重要的数据包:SCAN_REQ, SCAN_RSP 和 CONNECT_REQ.    SCAN_REQ: 扫描请求, ...

  6. Udp数据接收和发送代码

    每一台电脑都有自己的ip地址,向指定的ip地址发数据,数据就发送到了指定的电脑.UDP通信只是一种通信方式而已,有了ip地址数据就能发送到指定的电脑了,但是呢!我把数据发送到电脑了,电脑中的哪个程序接 ...

  7. C#对串口数据接收、发送的处理

    最近在做与设备进行串口通信交互的项目,然后简单记录一下过程 使用的winform应用程序 方式1 1.声明串口对象 或者直接在工具箱拖拽串口控件 本篇文章不采用拖拽工具箱控件 直接声明对象 声明串口对 ...

  8. View Programming Guide for iOS官方文档翻译一

    版权声明:本文为博主原创文章,转载请声明出处,谢谢! 本文档的官方英文原版地址 关于窗口和视图 在iOS中,您可以使用窗口(windows)和视图(views)在屏幕上显示APP的内容. 窗口(Win ...

  9. 【iOS官方文档翻译】UICollectionView与UICollectionViewFlowLayout

    (一)先来简单回顾一下UICollectionView *UICollectionView的简单使用可以看我以前写的这篇博文:UICollectionView的基本使用 UICollectionVie ...

最新文章

  1. 第五百六十四天 how can I 坚持
  2. iOS 自定义UITabBar
  3. 世界上最百变的人不是女友,竟然是......
  4. MYSQL 取中位数
  5. Linux/Unix系统编程手册 第三章:系统编程概念
  6. IM推送保障及网络优化详解(二):如何做长连接加推送组合方案
  7. boost::irange相关的测试程序
  8. vs2013 c# 中调用 c 编写的dll出错的可能错误
  9. 第八十九期:还在手动盖楼领喵币?双十一这群开发者竟然如此「作弊」
  10. 使用CNN进行情感分类
  11. php array_key_exists() 与 isset() 的区别
  12. 百度文库免费下载方法,亲测可用!建议收藏!
  13. java 打印 xps_使用Java 将PPT转换为PDF、XPS等格式
  14. 怎么更改网络选项为家庭计算机,我的现在是公用网络我想更改为家庭网络应该如何更改...
  15. java 图片加多处水印_Java在Word中添加多行图片水印
  16. 《算法技术手册》一1.3.5 融会贯通
  17. 创造与魔法怎么自建服务器,创造与魔法自建服攻略大全_创造与魔法自建服建造方法、福利_玩游戏网...
  18. Linux驱动移植USB网卡r8156驱动(详细)总结
  19. h3c交换机配置远程管理_H3C交换机配置远程登录
  20. 分享154个ASP源码,总有一款适合您

热门文章

  1. bzoj 4813: [Cqoi2017]小Q的棋盘【树形dp】
  2. Animation Override Controller动画重载器
  3. Web开发的那点事--数据持久层常用功能
  4. C#用XmlDocument操作XML
  5. IE6,7,8,FF兼容总结
  6. apache日志分析简介
  7. DataGrid 的 全选/取消全选 控制(CheckBox)
  8. 【C++】new和malloc的区别
  9. 毕业季:理想很丰满,现实也可以很丰满!
  10. mysql分组和where条件查询_【MySQL】:分组查询where和having