苹果蓝牙后台的限制,原本广播会有两个段分别是localName和serviceUUID这两块,但现在后台广播时,是不发送在这两段的

手机app可以作为一个蓝牙外设端来模拟外设硬件,但广播包里的数据只能包含localName和serviceUUID,相对于外设硬件来说还是有一些不足之处。

一个128位的蓝牙UUID来标示

32个 x 是 0-9 或 a-f 范围内的一个十六进制的数字(0x00),X是字符串格式

把数据按uuid的格式加进去

self.peripheralManager startAdvertising:@{CBAdvertisementDataServiceUUIDsKey:serviceUUIDs,CBAdvertisementDataNameKey:localName}];

对应的值是数组

key: kCBAdvDataIsConnectable, value: 1

key: kCBAdvDataLocalName, value: SimpleBLEPeripheral

key: kCBAdvDataServiceUUIDs    //数据就在这里

       uuid(0): FF F0

key: kCBAdvDataTxPowerLevel, value: 0

Manufacturer Specific Data

NSArray *keys = [advertisementData allKeys];

NSData *dataAmb, *dataObj;

//获取所有的key

for (int i = 0; i < [keys count]; ++i) {

id key = [keys objectAtIndex: i];

NSString *keyName = (NSString *) key;

NSObject *value = [advertisementData objectForKey: key];

//处理所有的value

if ([value isKindOfClass: [NSArray class]]) {

printf("   key: %s\n", [keyName cStringUsingEncoding: NSUTF8StringEncoding]);

NSArray *values = (NSArray *) value;

//处理每个value里面的值

for (int j = 0; j < [values count]; ++j) {

if ([[values objectAtIndex: j] isKindOfClass: [CBUUID class]]) {

CBUUID *uuid = [values objectAtIndex: j];

NSData *data = uuid.data;  //获取到  uuid.data

if (j == 0) {

dataObj = uuid.data;

} else {

dataAmb = uuid.data;

}

printf("      uuid(%d):", j);

for (int j = 0; j < data.length; ++j)

printf(" %02X", ((UInt8 *) data.bytes)[j]);

printf("\n");

} else {

const char *valueString = [[value description] cStringUsingEncoding: NSUTF8StringEncoding];

printf("      value(%d): %s\n", j, valueString);

}

}

} else {

const char *valueString = [[value description] cStringUsingEncoding: NSUTF8StringEncoding];

printf("   key: %s, value: %s\n", [keyName cStringUsingEncoding: NSUTF8StringEncoding], valueString);

}

}

蓝牙周边后台执行模式

想要作为一个周边角色在后台工作,你需要在Info.plist文件中添加bluetooth-periphral到UIBackgroundModes关键字下。当你这么做了,系统会在你的app需要读,写,订阅事件的时候唤醒它。

除了可以在后台唤醒app处理连接的中心的读写订阅。蓝牙中心库还可以允许你的app在后台的时候广播。但是你需要了解app在后台的广播和在前台的广播状态不太一样。特别的,当你的app在后台广播时。

CBAdvertisementDataLocalNameKey 广告键是被忽略的,而且local name也不会被广播的

所以 CBAdvertisementDataServiceUUIDsKey中的服务UUID被放在一个“溢出”区,它们只能被明确搜索的iOS设备搜索到。

如果所有app都在后台广播,你的app的包广播频率会变少。

When you start advertising peripheral data, the peripheral manager calls the peripheralManagerDidStartAdvertising(_:error:) method of its delegate object.

Data advertising is done on a “best effort” basis, because space is limited and there may be multiple apps advertising simultaneously. While your app is in the foreground, it can use up to 28 bytes of space in the initial advertisement data for any combination of the supported advertising data keys. If this space is used up, there are an additional 10 bytes of space in the scan response that can be used only for the local name (represented by the value of the CBAdvertisementDataLocalNameKey key). Note that these sizes do not include the 2 bytes of header information that are required for each new data type. Any service universally unique identifiers (UUIDs) contained in the value of the CBAdvertisementDataServiceUUIDsKey key that do not fit in the allotted space are added to a special “overflow” area; they can be discovered only by an iOS device that is explicitly scanning for them. While your app is in the background, the local name is not advertised and all service UUIDs are placed in the overflow area. The exact format of advertising and response data is defined in the Bluetooth 4.0 specification, Volume 3, Part C, Section 11.

当开始广告外围设备数据时,外围设备管理器调用其委托对象的外围信息管理器didstartadvertising (_:error:)方法。

数据广告是在“尽最大努力”的基础上进行的,因为空间有限,同时可能有多个应用程序在做广告。当你的应用程序在前台时,它可以在初始广告数据中使用最多28字节的空间来组合支持的广告数据键。如果耗尽了这个空间,那么扫描响应中还有额外的10字节空间,只能用于本地名称(由CBAdvertisementDataLocalNameKey键值表示)。注意,这些大小不包括每个新数据类型所需的2个字节的头信息。在特定的“溢出”区域中添加不适合于分配的空间的CBAdvertisementDataServiceUUIDsKey键值中包含的任何服务通用惟一标识符(uuid);只有当iOS设备显式地扫描它们时,才能发现它们。当您的应用程序在后台时,本地名称没有广告,所有服务uuid都放置在溢出区域。广告和响应数据的确切格式定义在蓝牙4.0规范第3卷C部分第11节中。

在初始化中心或者周边管理者的时候选择是否需要支持状态的保存和恢复

在初始化时指定CBCentralManagerOptionRestoreIdentifierKey选项,并为中心管理者提供一个字符串作为“恢复标识”就可以了:

myCentralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil options:@{ CBCentralManagerOptionRestoreIdentifierKey: @"myCentralManagerIdentifier" }];

CBPeripheralManagerOptionRestoreIdentifierKey

恢复你的中心和周边管理者

当你的app在后台被系统重启时,你的第一件事就是根据“恢复标识”恢复适当的中心和周边管理者就像他们第一次创建时一样

当你的app被系统重启时,你可以检索系统为你的应用程序保留的中央管理器对象的所有恢复标识符,像这样:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { NSArray *centralManagerIdentifiers = launchOptions[UIApplicationLaunchOptionsBluetoothCentralsKey];

在拿到恢复标示符之后,只需要遍历并恢复适当的中央管理者。

- (void)centralManager:(CBCentralManager *)central willRestoreState:(NSDictionary *)state { NSArray *peripherals = state[CBCentralManagerRestoredStatePeripheralsKey]; ...

iOS 作为蓝牙外设广播信息的更多相关文章

  1. esp32使iOS 获取蓝牙外设的Mac地址

    最近在做一个需要上下位机的项目,我负责的任务下位机,使用的主控芯片是esp32.这个项目中有一项是需要手机扫描二维码然后连接作为esp32的蓝牙.二维码中包含了mac地址信息,在手机扫描周围设备的时候 ...

  2. 微信小程序之蓝牙广播信息

    期初第一次做蓝牙开锁的时候遇到的最尖锐的问题就是ios设备如何对获取的广播信息进行读取,大概用了4中方式,都无法解决,最后不得不求助官方人员.给了一个方法,大家可以参考.在此附图: 由于mac地址是6 ...

  3. ios设备app作为蓝牙外设端

    苹果手机可以作为蓝牙外设端,被蓝牙中央端来扫描连接交互数据,实现模拟蓝牙外设硬件.通过阅读CoreBluetooth库,可以找到一个CBPeripheralManager的类,该类主要的作用就是允许你 ...

  4. iOS之 PJSIP蓝牙外设音频支持

    如题,蓝牙设备作为音频输出,在app中如果包含VoIP那么就要设定当连接蓝牙设备时候是否选择或者支持蓝牙输出 最近在处理一个工单就是公司的voip-app与硬件话机底座联调(蓝牙2.0)坑爹的如果是4 ...

  5. iOS - App 与外设间的通信方式

    1.前言 一般 iOS 开发者做 App 开发大部分时候都是通过 Http(s) 请求跟后台服务器打交道,做一些信息展示和用户交互.很少涉及到去跟外部硬件设备连接的开发.随着近年来车联网和物联网的兴起 ...

  6. iOS之蓝牙开发—CoreBluetooth详解

    CoreBluetooth的API是基于BLE4.0的标准的.这个框架涵盖了BLE标准的所有细节.仅仅只有新的iOS设备和Mac是和BLE标准兼容.在CoreBluetooth框架中,有两个主要的角色 ...

  7. iOS,蓝牙开发!!--By帮雷

    iOS的蓝牙开发大致有以下几种方式. 1 GameKit.framework [只能存在于iOS设备之间,多用于游戏 能搜索到的demo比较多,不确切说名字了,code4app里面就有] 2 Core ...

  8. iOS关于蓝牙连接的简单介绍与使用

    下面是两台iPhone6连接同一台蓝牙设备的结果: **成功连接**** peripheral: <CBPeripheral: 0x1700f4500, identifier = 50084F6 ...

  9. ios获取CELLID,LAC等信息方法

    搞了一个来月的这个东西了,还是没有完全解决问题,下面方法可以获取简单的Cell信息,方法一://CoreTelephony.h//主要就这两个结构体,其他需要的话,自己添加struct CTServe ...

随机推荐

  1. DATEADD (Transact-SQL)

    DATEADD (Transact-SQL) This function adds a specified number value (as a signed integer) to a specif ...

  2. Deep-learning augmented RNA-seq analysis of transcript splicing | 用深度学习预测可变剪切

    可变剪切的预测已经很流行了,目前主要有两个流派: 用DNA序列以及variant来预测可变剪切:GeneSplicer.MaxEntScan.dbscSNV.S-CAP.MMSplice.clinVa ...

  3. CgLib实现AOP

    一.CgLib实现动态代理的例子 1.创建Person类 package com.example.cglib; public class Person { public void study(){ S ...

  4. 接口测试01- Jmeter-线程进程-环境变量

    1.1 概念 JMeter 是 Apache 组织使用 Java 开发的一款测试工具 ,它最初被设计用于Web应用测试,但后来扩展到其他测试领域. 它可以用于测试静态和动态资源,例如静态文件.Java ...

  5. 转 : 请问mysql如何确定一个库是主库还是从库。

    select user,host from mysql.user;SELECT Repl_slave_priv,Repl_client_priv,super_priv,host FROM mysql. ...

  6. Linux云主机(离线)搭建本地yum源

    下载CentOS镜像 http://mirror.nsc.liu.se/centos-store/7.3.1611/isos/x86_64/ 离线yum源的配置 1.上传下载的镜像源iso 2.挂载i ...

  7. 开发日记:常用BAT批处理

    备份文件:BackupSourceCode.bat ::自动备份当前文件夹 ::by luomg, 21:15 2010-10-13 ::minguiluo@163.com @echo off tit ...

  8. 基于EasyNVR摄像机无插件直播方案二次开发实现自己的摄像机IPC-NVR无插件化直播解决方案

    背景介绍 在之前的博客中<基于EasyNVR实现RTSP/Onvif监控摄像头Web无插件化直播监控>,对EasyNVR所实现的功能我们已经有较多描述,这些也在方案地址:http://ww ...

  9. Tomcat免安装版执行tomcat9.exe闪退

    Tomcat免安装版点击startup.bat可成功启动,但是执行tomcat9.exe时却闪退,这是因为免安装版的tomcat不会自动把tomcat注册到windows服务里,需要手动注册. 解决办 ...

  10. .Net Core使用 MiniProfiler 进行性能分析

    官方文档: https://miniprofiler.com/dotnet/AspDotNetCore 1.添加包 MiniProfiler.AspNetCore.Mvc   和    MiniPro ...