iOS小技能: app因蓝牙功能隐蔽而导致上架被拒绝的解决方案

前言

本文主要记录一次关于蓝牙权限被拒绝上架的问题。

I 、蓝牙权限被拒绝上架

1.1 案例1

拒绝原因

Your app declares support for bluetooth-central in the UIBackgroundModes key in your Info.plist but does not provide Bluetooth Low Energy functionality. The Bluetooth Background modes are for apps that communicate to other devices using Bluetooth Low Energy and the Core Bluetooth framework.

真正的原因是审核人员没发现使用蓝牙的功能,所以打回了

解决方案: 因app中的蓝牙功能隐蔽而导致上架被拒绝的解决方案

1.2 案例2

背景:基于安全策略,限制国外访问服务器API,上架被拒 上架前申请开放权限

x x总,您好:xx子公司将于12月28号早上提交xxAPP到IOS市场审核,期间申请放开国外访问xx的限制(放开时间预计需要3-4个工作日),允许通过IPv6网络访问xx(不限于美国,其他国家也能访问),避免xxAPP在IOS应用市场审核失败,望领导审批,谢谢!

回复限制网络访问的文案

您好,亲爱的苹果审核团队,由于我们服务器的原因导致无法登录,现已修复请重新审核。非常感谢!

II、 蓝牙权限设置

  • UIBackgroundModes key小知识点

bluetooth-central 使用核心蓝牙框架和周边BLE设备通信 bluetooth-peripheral 使用核心蓝牙框架共享数据

2.1 后台执行模式

Core Bluetooth Background Execution Modes

有两种蓝牙后台模式,一种为central角色,另一种为peripheral角色。如果应用需要两种角色,则可以声明支持两种模式。

声明方式:增加UIBackgroundModes 键,并增加包含下列字符串的array值。

  • bluetooth-central—The app communicates with Bluetooth low energy peripherals using the Core Bluetooth framework.
  • bluetooth-peripheral—The app shares data using the Core Bluetooth framework

那么应用将可以在后台处理特定的蓝牙相关事件。即使在后台,你仍然可以发现和连接peripherals,可以检索和读写数据。并且当有CBCentralManagerDelegate or CBPeripheralDelegate 代理事件发生时,系统会唤醒应用来处理

需要注意的是,进入后台时,扫描的处理有些区别:1, CBCentralManagerScanOptionAllowDuplicatesKey 这个键会被忽略,多次发现同一peripheral会被合并成一个发现事件。2,如果所有扫描中的应用都在后台,那么你应用的扫描间隙会延长。结果是,扫描到peripheral的时间可能会延长。

这样做是为了减少辐射节省电量。

2.2 支持peripheral后台运行的模式

如果要支持peripheral角色的后台模式,你需要在Info.plist中的增加UIBackgroundModes键并在值中包含bluetooth-peripheral值。这样系统会唤醒应用来处理读写和订阅事件。

蓝牙框架(Core Bluetooth framework)不仅允许你的应用被唤醒来处理读写和订阅请求,还允许你的应用在后台状态下发送广播。但你必须注意后台时广播与前台时广播是不同的。即便如此,你必须注意后台与前台时广播处理的区别。特别是当你的应用需要在后台发送广播。1,CBAdvertisementDataLocalNameKey 这个键会被忽略,并且peripheral的local name不会被广播 2,CBAdvertisementDataServiceUUIDsKey 的值中包含的所有service uuids都会被放到“overflow”区域;只有ios设备显示指明在搜索它时才会搜索到这些值。3,如果所有的处于广播状态的应用都在后台,广播频率将降低。

2.3 支持bluetooth-central后台运行的模式

支持打印码牌交易小票的蓝牙权限设置,实现这个功能的时候,使用的API 需要打开specified the "bluetooth-central" background mode' 否则报错信息如下

2019-12-20 10:02:28.602776+0800 retail[64492:7143836] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'State restoration of CBCentralManager is only allowed for applications that have specified the "bluetooth-central" background mode'

具体的错误信息:

2019-12-20 10:01:27.337095+0800 retail[64492:7143836] *** Assertion failure in -[CBCentralManager initWithDelegate:queue:options:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/MobileBluetoothFramework/MobileBluetooth-125.10.1/CoreBluetooth/CoreBluetooth/CBCentralManager.m:203
2019-12-20 10:02:28.537998+0800 retail[64492:7144702] centralManagerDidUpdateState: 5
2019-12-20 10:02:28.602776+0800 retail[64492:7143836] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'State restoration of CBCentralManager is only allowed for applications that have specified the "bluetooth-central" background mode'
*** First throw call stack:
(0x18525127c 0x18442b9f8 0x18516a988 0x185c2e188 0x18acdee24 0x101dd04ac 0x101dd0370 0x1013bf968 0x1013bf8b8 0x1015c773c 0x10139cfe0 0x1b146f7c4 0x1b13d0e90 0x1b146f7c4 0x1b1470128 0x1b1396da4 0x1b139f934 0x1b139ac04 0x1b1492cc8 0x1b1a1edec 0x1b1a0d93c 0x1b1a3a7ac 0x1851e25f8 0x1851dd320 0x1851dd89c 0x1851dd0b0 0x1873dd79c 0x1b1a13978 0x1016f45ac 0x184ca28e0)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb) c

2.4 UIBackgroundModes的配置

  1. 在UIBackgroundModes中添加了bluetooth-central关键字在Info.plist以实现中心角色。

核心蓝牙框架允许你的app在后台运行以执行一些中心蓝牙相关的任务。当你的app在后台时,你仍然可以搜索连接周边设备,和周边设备通信,交换数据。另外,系统会在任何 CBCentralManagerDelegate 或 CBPeripheralDelegate 的回调方法被调用时唤醒你的app,允许你的app处理重要的中心角色事件,比方说连接突然断了,周边角色上报数据了,中心管理者的状态发生改变。

CBCentralManagerScanOptionAllowDuplicatesKey 的搜索选项将被忽略,多次扫描的结果会被合并为同一个事件

初始化CBCentralManager

//    // CBCentralManagerOptionShowPowerAlertKey:初始化的时候如果蓝牙没打开会弹出提示框
        // CBCentralManagerOptionRestoreIdentifierKey:用于蓝牙进程被杀掉恢复连接时用的
        _centralmanager =[[CBCentralManager alloc] initWithDelegate:self queue:dispatch_get_global_queue(0, 0) options:@{CBCentralManagerOptionShowPowerAlertKey      : [NSNumber numberWithBool:YES]}];

若想利用使用这些提示,你需要在调用connectPeripheral:options: 方法时传入如下参数。CBConnectPeripheralOptionNotifyOnConnectionKey: 在应用挂起后,与指定的peripheral成功建立连接,则发出通知,进行打印操作?CBConnectPeripheralOptionNotifyOnDisconnectionKey: 在应用挂起后,如果与指定的peripheral断开连接,则发出通知,进行重新连接?CBConnectPeripheralOptionNotifyOnNotificationKey: 在应用挂起后,指定的peripheral有任何通知都进行提示

  1. 蓝牙周边后台执行模式:bluetooth-periphral

想要作为一个周边角色在后台工作,你需要在Info.plist文件中添加bluetooth-periphral到UIBackgroundModes关键字下。当你这么做了,系统会在你的app需要读,写,订阅事件的时候唤醒它。除了可以在后台唤醒app处理连接的中心的读写订阅。蓝牙中心库还可以允许你的app在后台的时候广播。

CBAdvertisementDataLocalNameKey 广告键是被忽略的,而且local name也不会被广播的 所以 CBAdvertisementDataServiceUUIDsKey中的服务UUID被放在一个“溢出”区,它们只能被明确搜索的iOS设备搜索到。

see also

上一篇:iOS上传图片视图的封装:用法 【下篇】


下一篇:GCC和clang的区别