概述

iOS蓝牙BLE4.0通信功能,最近刚学的苹果,为了实现蓝牙门锁的项目,找了一天学习了下蓝牙的原理,亲手测试了一次蓝牙的通信功能,结果成功了,那么就把我学习的东西分享一下。

详细

代码下载:http://www.demodashi.com/demo/10635.html

一、蓝牙常见名称和缩写

  • BLE:(Bluetooth low energy)蓝牙4.0设备因为低耗电

  • BLE:(Bluetooth low energy)蓝牙4.0设备因为低耗电

  • Central:中心设备,发起蓝牙连接的设备(一般是指手机)

  • Peripheral:外设,被蓝牙连接的设备(一般是运动手环)

  • Service and Characteristic:服务和特征,每个设备会提供服务和特征,类似于服务端的API,但是结构不同,每个设备会有很多服务,每个服务中包含很多特征,这些特征的权限一般分为读(read),写(write),通知(notify)几种,就是我们连接设备后具体需要操作的内容

  • Description:描述,每个Characteristic可以对应一个或者多个Description用于描述Characteristic的信息或属性

二、蓝牙基础知识

1、CoreBluetooth框架的核心其实是俩东西

  • Peripheral

  • Central

2、这两组api分别对应不同的业务常见

  • 左侧叫中心模式,就是以你的app作为中心,连接其他的外设的场景

  • 右侧称为外设模式,使用外设连接其他中心设备操作的场景

3、服务和特征(service and characteristic)

  • 每个设备都会有1个or多个服务

  • 每个服务里都会有1个or多个特征

  • 特征就是具体键值对,提供数据的地方

  • 每个特征属性分为:读,写,通知等等

外设,服务,特征的关系

三、BLE中心模式流程

1、建立中心角色

2、扫描外设(Discover Peripheral)

3、连接外设(Connect Peripheral)

4、扫描外设中的服务和特征(Discover Services And Characteristics)

4.1 获取外设的services

4.2 获取外设的Characteristics,获取characteristics的值

4.3 获取Characteristics的Descriptor和Descriptor的值

5、利用特征与外设做数据交互

6、订阅Characteristic的通知

7、断开连接(Disconnect)

四、准备工作

1、一台苹果设备,进行真机测试

2、一个蓝牙模块或者外设

五、程序实现

项目代码截图:

以下是实现的过程:

1、导入依赖库、声明委托、定义变量

#import "ViewController.h"
#import <CoreBluetooth/CoreBluetooth.h>#define mBLEName @"ZJ2"@interface ViewController () <CBCentralManagerDelegate, CBPeripheralDelegate>
//手机设备
@property (nonatomic, strong) CBCentralManager *mCentral;
//外设设备
@property (nonatomic, strong) CBPeripheral *mPeripheral;
//特征值
@property (nonatomic, strong) CBCharacteristic *mCharacteristic;
//服务
@property (nonatomic, strong) CBService *mService;
//描述
@property (nonatomic, strong) CBDescriptor *mDescriptor;@end

2、程序开始时初始化设备

- (CBCentralManager *)mCentral
{if (!_mCentral) {_mCentral = [[CBCentralManager alloc] initWithDelegate:selfqueue:dispatch_get_main_queue()options:nil];}return _mCentral;
}- (void)viewDidLoad
{[super viewDidLoad];//中心管理者初始化[self mCentral];
}

3、当程序退出时,记得断开连接

- (void)viewDidDisappear:(BOOL)animated
{[super viewDidDisappear:animated];// 停止扫描if([self.mCentral isScanning]){NSLog(@"stopScan");[self.mCentral stopScan];}//停止连接if(nil != self.mPeripheral && self.mPeripheral.state == CBPeripheralStateConnecting){NSLog(@"cancelPeripheralConnection");[self.mCentral cancelPeripheralConnection:self.mPeripheral];}
}

4、扫描外设

//只要中心管理者初始化,就会触发此代理方法
- (void)centralManagerDidUpdateState:(CBCentralManager *)central
{switch (central.state) {case CBManagerStateUnknown:NSLog(@"CBManagerStateUnknown");break;case CBManagerStateResetting:NSLog(@"CBManagerStateResetting");break;case CBManagerStateUnsupported:NSLog(@"CBManagerStateUnsupported");break;case CBManagerStateUnauthorized:NSLog(@"CBManagerStateUnauthorized");break;case CBManagerStatePoweredOff:NSLog(@"CBManagerStatePoweredOff");break;case CBManagerStatePoweredOn:{NSLog(@"CBManagerStatePoweredOn");//搜索外设[self.mCentral scanForPeripheralsWithServices:nil // 通过某些服务筛选外设options:nil]; // dict,条件}break;default:break;}
}

5、连接外设

//发现外设后调用的方法
- (void)centralManager:(CBCentralManager *)central // 中心管理者didDiscoverPeripheral:(CBPeripheral *)peripheral // 外设advertisementData:(NSDictionary *)advertisementData // 外设携带的数据RSSI:(NSNumber *)RSSI // 外设发出的蓝牙信号强度
{NSLog(@"搜索到设备名:%@,设备ID:%@",peripheral.name,peripheral.identifier);//(ABS(RSSI.integerValue) > 35)//发现完之后就是进行连接if([peripheral.name isEqualToString:mBLEName]){self.mPeripheral = peripheral;self.mPeripheral.delegate = self;[self.mCentral connectPeripheral:peripheral options:nil];}
}

6、获取服务

//中心管理者连接外设成功
- (void)centralManager:(CBCentralManager *)central // 中心管理者didConnectPeripheral:(CBPeripheral *)peripheral // 外设
{NSLog(@"设备连接成功,设备名:%@", peripheral.name);//7、外设发现服务,传nil代表不过滤[self.mPeripheral discoverServices:nil];
}// 外设连接失败
- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error
{NSLog(@"设备连接失败,设备名:%@", peripheral.name);
}// 丢失连接
- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error
{NSLog(@"设备丢失连接,设备名:%@", peripheral.name);
}

7、获取服务中的特征

//发现外设的服务后调用的方法
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error
{// 是否获取失败if (error) {NSLog(@"设备获取服务失败,设备名:%@", peripheral.name);return;}for (CBService *service in peripheral.services) {self.mService = service;NSLog(@"设备获取服务成功,服务名:%@,服务UUID:%@,服务数量:%lu",service,service.UUID,peripheral.services.count);//外设发现特征[peripheral discoverCharacteristics:nil forService:service];}
}

8、获取特征中的值和描述

//从服务中发现外设特征的时候调用的代理方法
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error
{if(error){NSLog(@"设备获取特征失败,设备名:%@", peripheral.name);return;}/**CBCharacteristicPropertyRead                                                 = 0x02,CBCharacteristicPropertyWriteWithoutResponse                                    = 0x04,CBCharacteristicPropertyWrite                                                   = 0x08,CBCharacteristicPropertyNotify                                                  = 0x10,*/for (CBCharacteristic *cha in service.characteristics) {if(cha.properties & CBCharacteristicPropertyWrite){NSLog(@"CBCharacteristicPropertyWrite");NSLog(@"%lu",cha.properties & CBCharacteristicPropertyWrite);self.mCharacteristic = cha;}else if(cha.properties & CBCharacteristicPropertyWriteWithoutResponse){NSLog(@"CBCharacteristicPropertyWriteWithoutResponse");}else if(cha.properties & CBCharacteristicPropertyRead){NSLog(@"CBCharacteristicPropertyRead");}else if(cha.properties & CBCharacteristicPropertyNotify){NSLog(@"CBCharacteristicPropertyNotify");}else if(cha.properties & CBCharacteristicPropertyIndicate){NSLog(@"CBCharacteristicPropertyIndicate");}NSLog(@"设备获取特征成功,服务名:%@,特征值名:%@,特征UUID:%@,特征数量:%lu",service,cha,cha.UUID,service.characteristics.count);//获取特征对应的描述 会回调didDiscoverDescriptorsForCharacteristic[peripheral discoverDescriptorsForCharacteristic:cha];//获取特征的值 会回调didUpdateValueForCharacteristic[peripheral readValueForCharacteristic:cha];}if(nil != self.mCharacteristic){//打开外设的通知,否则无法接受数据[peripheral setNotifyValue:YES forCharacteristic:self.mCharacteristic];}
}

9、读取特征中的值和描述

//更新特征值的时候调用,可以理解为获取蓝牙发回的数据
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
{NSString *value = [[NSString alloc] initWithData:characteristic.value encoding:NSASCIIStringEncoding];NSLog(@"特征名:%@,特征值:%@",characteristic,value);if([value isEqualToString:@"open"]){}else if([value isEqualToString:@"close"]){}
}

10、状态改变和发现描述

//通知状态改变时调用
-(void)peripheral:(CBPeripheral *)peripheral didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error{if(error){NSLog(@"特征名:%@,改变通知状态失败",characteristic);}NSLog(@"特征名:%@,改变了通知状态",characteristic);
}//发现外设的特征的描述数组
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverDescriptorsForCharacteristic:(nonnull CBCharacteristic *)characteristic error:(nullable NSError *)error
{if(error){NSLog(@"设备获取描述失败,设备名:%@", peripheral.name);return;}for (CBDescriptor *descriptor in characteristic.descriptors) {self.mDescriptor = descriptor;[peripheral readValueForDescriptor:descriptor];NSLog(@"设备获取描述成功,描述名:%@",descriptor);}
}

11、发送数据

//发送数据
-(void)sendDataToBLE:(NSString *)data{NSData* myData = [data dataUsingEncoding:NSUTF8StringEncoding];[self.mPeripheral writeValue:myData // 写入的数据forCharacteristic:self.mCharacteristic // 写给哪个特征type:CBCharacteristicWriteWithResponse];// 通过此响应记录是否成功写入
}-(void)peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error{NSLog(@"数据发送成功");
}

六、运行效果

从电脑串口助手可以看到,发送了两次的D3数据,手机也收到了两次11的数据

这里使用的是蓝牙模块Risym cc2541和苹果手机实现两者的通信功能,根据BLE中心模式流程走就可以了

下面是手机设备NSLog打印输出的结果,从连接到发送数据和接收数据的过程。

(查看大图)

可以发现连接成功后,设备有两个服务,第一个服务对应有九个特征值,第二个服务对应有一个特征值,验证了上面的原理是正确的

(查看大图)

七、其他补充

CSDN博客地址:http://blog.csdn.net/qq_30379689/article/details/61413950

CSDN课程地址:http://edu.csdn.net/course/detail/4534

注:本文著作权归作者,由demo大师(http://www.demodashi.com)宣传,拒绝转载,转载需要作者授权

iOS蓝牙BLE4.0通信功能相关推荐

  1. iOS 蓝牙 4.0 开发

    随着蓝牙低功耗技术BLE(Bluetooth Low Energy)的发展,蓝牙技术正在一步步成熟,如今的大部分移动设备都配备有蓝牙4.0,相比之前的蓝牙技术耗电量大大降低.从iOS的发展史也不难看出 ...

  2. iOS 蓝牙4.0开发使用(内附Demo)

    一: 介绍 近几年,智能设备越来越火,这些智能设备中,有很大一部分是通过手机来控制硬件设备,来达到预期的效果,这中间少不了要使用到蓝牙功能,通过蓝牙来通信来控制设备. 蓝牙分为蓝牙2.0和蓝牙4.0. ...

  3. IOS蓝牙4.0与读卡器通讯

    IOS学习也一段时间了,该上点干货了.前段时间研究了一下IOS蓝牙通讯相关的东西,把研究的一个成果给大家分享一下. 一 项目背景 简单介绍一下做的东西,设备是一个金融刷卡器,通过蓝牙与iphone手机 ...

  4. iOS 蓝牙4.0开发

    1. 什么是蓝牙 4.0 ?   全新的蓝牙4.0技术并不是一种技术,而是由传统蓝牙,高速蓝牙和低功耗蓝牙合而为一.并且这三种蓝牙可以组合使用,也可以单独使用.其中,低功耗蓝牙即BLE是蓝牙4.0的核 ...

  5. 安卓蓝牙4.0通信之Socket图片传输

    安卓蓝牙4.0Socket通信传输图片 开发环境介绍: 开发工具:AndroidStudio 3.1.2 测试机:华为荣耀八青春版 安卓8.0(7.0) 红米note1S(4.4) SDK版本:28 ...

  6. OC 血压计 蓝牙BLE4.0 链接踩坑开发

    # 前言 公司项目要连接第三方公司的血压计,由于从来没有做过和蓝牙有关的项目,好奇的心驱使下下也想顺便了解一下这方面的知识,于是主动向领导请求开发这个功能,经过4天的折腾,终于弄好了,(为什么要4天呢 ...

  7. CC2541蓝牙BLE4.0主从透传工程

    .前言 小弟初来乍到,这是小弟的第一篇博客,暂时还在上学,没有什么工作经验,本篇博客主要记录我在这几天学习BLE协议协议栈的一点心得体会,并用一个主从透传的实验来记录过程,如有错误之处,还望各位大佬多 ...

  8. android 蓝牙4.0广播功能应用

    一.添加蓝牙权限 在AndroidManifest.xml文件中添加如下红色部分代码,添加蓝牙打开权限,以及LE接口调用权限. <?xml version="1.0" enc ...

  9. 菜鸟哥玩蓝牙Ble4.0系列 ESP32初玩篇① Scan —— 扫描周边蓝牙,了解BLE扫描的方方面面

    文章目录 1.前言 2.ESP32 Scan案例 2.1 直接打开官方示例 3.Scan核心库 -- BLEScan 3.1 管理扫描 3.1.1 创建扫描对象 -- BLEScan 3.1.1.1 ...

最新文章

  1. 利刃 MVVMLight 8:DispatchHelper在多线程和调度中的使用
  2. windows清理_Windows系统高级清理工具,实力吊打360!
  3. bt下载加速 BitTorrent trackers服务器列表
  4. Android主线程耗时动画卡顿,Android性能优化实战之界面卡顿
  5. 芬兰计算机研究生申请表,芬兰的研究生申请技巧
  6. Java阻塞队列 LinkedBlockingDeque
  7. react native中有关日期的组件DatePicker 示例
  8. 大数据WEB阶段(六)MySql 下载、安装、卸载与配置
  9. 提升你的代码——Lambda!
  10. 解析统计文本文件中的字符数、单词数、行数。
  11. 数组中的两个常见异常
  12. Python 给字符串进行加密,生成唯一固定长度字符串
  13. 近期新机发布一览:最便宜的只需699元!
  14. 基于JAVA+Swing+MYSQL的宿舍管理系统
  15. spring cloud 学习(6) - zuul 微服务网关
  16. App个人信息保护合规十大常见问题及处置策略
  17. FreeRTOS学习教程整理
  18. 树莓派安装centos系统
  19. Win10 dell驱动触摸板安装
  20. xcode 打包ipa

热门文章

  1. 飞桨PaddleHub实现皮影戏
  2. vivado fpga最最简单的入门--led闪烁 创建工程+代码输入+添加引脚约束完整具体流程
  3. 【AD】AD20差分等长布线
  4. 【STM32】【STM32CubeMX】STM32CubeMX的使用之四:IIC总线协议驱动SHT30温湿度传感器
  5. 第五章——微型计算机与外设的数据传输
  6. tigervnc远程控制linux,CentOS 6.8 安装TigerVNC 实现 Linux 远程桌面
  7. 位操作符:与,或,异或 狼羊菜
  8. mysql to_minute_mysql的时间转化
  9. cocoscreator3d 获取mesh 大小_Cocos Creator 3D 粒子系统初战: 不要钱的酷炫火焰拿走不谢!...
  10. 解决win-server 2008R2 安装 Materials 出现 Windows Install Coordinator “应用程序正在为首次安装做准备”...