iOS蓝牙(BLE4.0低功耗)详细渗透讲解

iOS 蓝牙4.0开发使用

嗨大家好,我是iOS开发一枚大帅比,过去的几年项目涉及到蓝牙比较多,抽空之余,把使用的小知识点归纳起来,一是方便自己对知识做很好的总结和复习,二是希望能帮助到琅琊开发的朋友们。

一、简介(什么是BLE4.0?哪里使用它?)

现在的互联网时代,智能硬件设备越来越多样化,这些设备中,有多是通过手机来控制硬件设备,来达到控制的效果,这中间少不了要使用到蓝牙功能,通过蓝牙来通信来控制设备。也就是我们说的“设备中心和外设的故事”。

蓝牙版本介绍:

每个人对于蓝牙都不陌生,近距离数据传输,方便;可是当你的业务需求需要你第一次接触蓝牙开发的时候,却会发现你对它并不了解;首先,蓝牙发展至今经历了8个版本的更新。1.1、1.2、2.0、2.1、3.0、4.0、4.1、4.2。那么在1.x~3.0之间的我们称之为传统蓝牙,4.x开始的蓝牙我们称之为低功耗蓝牙也就是蓝牙ble,当然4.x版本的蓝牙也是向下兼容的。android手机必须系统版本4.3及以上才支持BLE API。低功耗蓝牙较传统蓝牙,传输速度更快,覆盖范围更广,安全性更高,延迟更短,耗电极低等等优点。(现在的穿戴设备都是使用BLE蓝牙技术的)

传统蓝牙与低功耗蓝牙通信方式也有所不同,传统的一般通过socket方式,而低功耗蓝牙是通过Gatt协议来实现。

本文章目的便是介绍BLE 4.0的使用以及相关问题的解决,本文采用简要模式介绍BLE4.0的核心类的使用以及蓝牙开发的简介,如需了解蓝牙知识的详细知识点,百度可搜索其他大神的文章进行学习,下文通用BLE代为蓝牙4.0。

二、BLE的核心模式

BLE的两种模式分为CBCentralMannager 中心模式 和CBPeripheralManager 外设模式,在这里主要和大家分享CBCentralMannager 中心模式的开发和使用。

CBCentralMannager 中心模式

以手机(app)作为设备中心,连接其他外设(硬件)的场景。详细流程如下:

1、建立中心角色

2、扫描外设

3、发现外设

4、连接外设:

    1.连接失败

    2. 连接断开

    3.连接成功

5、扫描外设中的服务

    1.发现并获取外设中的服务Service

6、扫描外设对应服务的特征

    1.发现并获取外设对应服务的特征Characteristic

    2.给对应特征写数据

    3.订阅特征的通知 7.1 根据特征读取数据

说明:Service,Characteristic是每个硬件设备出厂设定的设备服务和特征值,用UUID作为唯一标识符。UUID为这种格式:0000ffe1-0000-1000-8000-00805f9b34fb。比如有3个Service,那么就有三个不同的UUID与Service对应。这些UUID都写在硬件里,我们通过BLE提供的API可以读取到,一个BLE终端可以包含多个Service, 一个Service可以包含多个Characteristic,一个Characteristic包含一个value和多个Descriptor,一个Descriptor包含一个Value。Characteristic是比较重要的,是手机与BLE终端交换数据的关键,读取设置数据等操作都是操作Characteristic的相关属性。说白了,我们可以把每个服务特征值看成是我们网络请求的api接口,我们和蓝牙的交互,是要连接到对应的service和对应的Characteristic才可以正确读取到和硬件文档以及出厂定制好的服务和数据。

三、CBPeriphera

暂且把这个小可爱理解为你所能发现搜索到的外设(硬件)对象,蓝牙硬件的信息都包含在它里面

下面我们看下这个类所包含的内容:

CB_EXTERN_CLASS @interface CBPeripheral : CBPeer

//代理

@property(weak, nonatomic, nullable) id<CBPeripheralDelegate> delegate;

//我们所能搜索到的外设名称

@property(retain, readonly, nullable) NSString *name;

//信号强度

@property(retain, readonly, nullable) NSNumber *RSSI;

//设备状态,包含以下4种状态

@property(readonly) CBPeripheralState state;

typedef NS_ENUM(NSInteger, CBPeripheralState) {

CBPeripheralStateDisconnected = 0,

CBPeripheralStateConnecting,

CBPeripheralStateConnected,

CBPeripheralStateDisconnecting

}

//服务群组

@property(retain, readonly, nullable) NSArray<CBService *> *services;

由于函数和属性太多,我只列举主要的几个,其他的可在代码中点击查看即可

四、使用步骤概要

1、导入:#import <CoreBluetooth/CoreBluetooth.h>

2、遵守CBCentralManagerDelegate,CBPeripheralDelegate协议

3、初始化中心Manager,创建中心角色

为了方便引用,一般把manager声明为一个属性对象:

@property (nonatomic, strong) CBCentralManager * centralManager;

 self.centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];

注:queue为你想把蓝牙初始化放到哪个队列,一般默认主队列

        options传nil即可,具体使用可查看策略含义

4、检查当前设备中心的蓝牙状态

// 状态更新时调用

- (void)centralManagerDidUpdateState:(CBCentralManager *)central

{

    switch (central.state) {

        case CBManagerStateUnknown:{

            NSLog(@"为知状态");

            self.peripheralState = central.state;

        }

            break;

        case CBManagerStateResetting:

        {

            NSLog(@"重置状态");

            self.peripheralState = central.state;

        }

            break;

        case CBManagerStateUnsupported:

        {

            NSLog(@"不支持的状态");

            self.peripheralState = central.state;

        }

            break;

        case CBManagerStateUnauthorized:

        {

            NSLog(@"未授权的状态");

            self.peripheralState = central.state;

        }

            break;

        case CBManagerStatePoweredOff:

        {

            NSLog(@"关闭状态");

            self.peripheralState = central.state;

        }

            break;

        case CBManagerStatePoweredOn:

        {

            NSLog(@"开启状态-可用状态");

            self.peripheralState = central.state;

            NSLog(@"%ld",(long)self.peripheralState);

        }

            break;

        default:

            break;

    }

}

5、开始扫描

if (self.peripheralState == CBManagerStatePoweredOn){

[self.centralManager scanForPeripheralsWithServices:nil options:nil];

}

6、发现外设

/**

扫描到设备

@param central 中心管理者

@param peripheral 扫描到的设备

@param advertisementData 广告信息

@param RSSI 信号强度

*/

- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary<NSString *,id> *)advertisementData RSSI:(NSNumber *)RSSI

{

    NSLog(@"%@",[NSString stringWithFormat:@"发现设备,设备名:%@",peripheral.name]);

}

7、连接外设

[self.centralManager connectPeripheral:peripheral options:nil];

      连接状态

/**

@param central 中心管理者

@param peripheral 连接失败的设备

@param error 错误信息

*/

** 连接失败 **

- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error

{

    NSLog(@"%@",@"连接失败");

}

** 连接断开 **

- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error { 

NSLog(@"%@",@"断开连接");

 }

** 连接成功 ** 

- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral { 

NSLog(@"连接设备:%@成功",peripheral.name);

 [self.centralManager stopScan]; 

}

8、扫描外设服务Service

// 设置设备的代理

peripheral.delegate = self;

// services:传入nil  代表扫描所有服务

[peripheral discoverServices:nil];

/**

扫描到服务

@param peripheral 服务对应的设备

@param error 扫描错误信息

*/

- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error

{

    // 遍历所有的服务

    for (CBService *service in peripheral.services)

    {

        NSLog(@"服务:%@",service.UUID.UUIDString);

    }

}

9、扫描service特征值

kWriteServerUUID 为和厂家协定好的,

例:读取电量的UUID:08B07DCB-13DD-435C-8BDA-04DA65BDC6AA

// 获取对应的服务

        if (![service.UUID.UUIDString isEqualToString:kWriteServerUUID])

        {

            return;

        }

        // 根据服务去扫描特征

        [peripheral discoverCharacteristics:nil forService:service];

10、给特征值写数据(就是发送指令)

[peripheral writeValue:data forCharacteristic:characteristic type:CBCharacteristicWriteWithResponse];

11、订阅特征值通知(订阅后可收到回应的数据)

if ([characteristic.UUID.UUIDString isEqualToString:kNotifyCharacteristicUUID]){

  [peripheral setNotifyValue:YES forCharacteristic:characteristic];

}

12、根据特征值读取数据(注:应把之前发送数据和订阅通知的peripheral和characteristic定义为全局属性)

*该处即为接收到外设发送的数据的方法

/**

根据特征读到数据

@param peripheral 读取到数据对应的设备

@param characteristic 特征

@param error 错误信息

*/

- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(nonnull CBCharacteristic *)characteristic error:(nullable NSError *)error

{

    if ([characteristic.UUID.UUIDString isEqualToString:kNotifyCharacteristicUUID])

    {

        NSData *data = characteristic.value;

        NSLog(@"%@",data);

    }

}

到这里,整个蓝牙使用的核心流程就基本介绍完了,鉴于写博客文章太累,太耗时,我决定先睡觉去,回头把文章慢慢细化一下,查漏补缺,格式可能也不是很完美,请读者们见谅,多提宝贵意见,喜欢的老铁们,可以点下喜欢或者收藏!

打个广告

本人github地址:shLuckySeven

欢迎去点star

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,922评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,591评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,546评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,467评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,553评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,580评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,588评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,334评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,780评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,092评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,270评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,925评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,573评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,194评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,437评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,154评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,127评论 2 352

推荐阅读更多精彩内容

  • 这里我们具体说明一下中心模式的应用场景。主设备(手机去扫描连接外设,发现外设服务和属性,操作服务和属性的应用。一般...
    丶逝水流年阅读 2,255评论 3 4
  • 本文主要以蓝牙4.0做介绍,因为现在iOS能用的蓝牙也就是只仅仅4.0的设备 用的库就是core bluetoot...
    暮雨飞烟阅读 836评论 0 2
  • 我的小姑子最近失恋了,整个人的精神一下子都垮掉了,整日萎靡不振,睡眼惺忪。正常的工作一天,下班就叫着累死了,推掉了...
    李若桃阅读 313评论 1 1
  • 02 今天,我刚下朝,贴身太监突然扑通一声给我跪了。“皇皇.....皇上,皇皇.....皇后她....她........
    琉璃信月阅读 185评论 0 0
  • 笑来老师告诉我们:“人最宝贵的是注意力。”这句话当时不知点燃了多少人,因为当你启动元认知能力的时候,就会知道自己浪...
    七公爱吃鸡阅读 397评论 0 0