海泉的博客

iOS13蓝牙隐私变化

Word count: 774Reading time: 3 min
2020/01/20 Share

1. 框架简要说明

iOS中Core Bluetooth 框架是一个抽象层,使开发人员可以访问BLE硬件。

苹果在WWDC 2019引入了许多改进措施。除了快速传输数据和节能连接之外,用户隐私也得到了很多重视。在iOS 12之前,应用程序可以在用户不知情的情况下访问蓝牙,例如连接到智能手表或无线耳机。但这样的做法有一些缺陷,会在用户的隐私中制造了一个漏洞。 开发人员可以利用此并跟踪诸如位置数据之类的信息。

但从iOS 13开始,如果在应用程序使用任何Core Bluetooth API,它都需要用户的许可。 当然用户可以从设置中开启、关闭蓝牙权限。

步骤

2. 隐私权限和使用

从iOS 13开始,开发人员必须通过在其info.plist文件中包含NSBluetoothAlwaysUsageDescription来指定蓝牙的隐私使用说明。 在没有使用说明的情况下访问Core Bluetooth将导致运行时崩溃。
为了向后支持较旧的iOS版本,还需要定义NSBluetoothPeripheralUsageDescription

屏幕快照 2020-01-01 下午5.52.50

3. API变更

CBManagerAuthorisation是iOS 13的一个新添加的属性。它用于确定蓝牙权限的授权状态。
授权属性可以具有以下任意状态:

  • allowedAlways
  • restricted
  • notDetermined
  • denied

IMG_4152

4. 使用步骤

import CoreBluetooth以便在代码库中使用 Core Bluetooth Framework。
为了使用Core Bluetooth功能,我们需要实现CBPeripheralDelegate和CBCentralManagerDelegate协议。

4.1 初始化蓝牙管理器

CBCentralManager负责扫描并连接到设备。 连接完成后,往后的操作都是围绕CBPeripheral进行的。

1
2
3
4
5
6
7
var centralManager: CBCentralManager?
var peripheral: CBPeripheral?

override func viewDidLoad() {
super.viewDidLoad()
centralManager = CBCentralManager(delegate: self, queue: nil)
}`

就在初始化CentralManager时,立即触发centralManagerDidUpdateState(_central:CBCentralManager)委托方法以检查蓝牙连接的状态。

如果蓝牙关闭,CBCentralManager不能被实例化,系统会自动提示抛出一个对话框,要求您启用它。

我们可以使用central.state.authorization属性检查用户授权状态。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
func centralManagerDidUpdateState(_ central: CBCentralManager) {
switch central.state {
case .unauthorized:
switch central.authorization {
case .allowedAlways:
case .denied:
case .restricted:
case .notDetermined:
}
case .unknown:
case .unsupported:
case .poweredOn:
self.centralManager?.scanForPeripherals(withServices: nil, options: [CBCentralManagerScanOptionAllowDuplicatesKey:true])
case .poweredOff:
case .resetting:
@unknown default:
}
}

仅当状态更改为poweredOn时才可以扫描设备

注意:Core Bluetooth仅扫描BLE设备。

4.2 连接到扫描的设备

一旦发现BLE设备,它将以下方法的委托方法回调:

1
2
3
4
5
6
7
8
func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {

self.peripheral = peripheral
self.peripheral?.delegate = self

centralManager?.connect(peripheral, options: nil)
centralManager?.stopScan()
}

然后,我们可以从peripheral.name属性访问蓝牙设备名称。

4.3 发送数据到设备
1
2
3
public func peripheral(_ peripheral: CBPeripheral, didWriteValueFor characteristic: CBCharacteristic, error: Error?) {
print(error ?? "data send successfully");
}
4.4 设备中数据有更新
1
2
3
public func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {

}

在这个代理方法中,可以上报给上层作进一步的数据处理。

5. 结论

苹果通过新的iOS 13权限提高了蓝牙安全性,以提供信息权限透明性并改善用户体验。

CATALOG
  1. 1. 1. 框架简要说明
  2. 2. 2. 隐私权限和使用
  3. 3. 3. API变更
  4. 4. 4. 使用步骤
    1. 4.1. 4.1 初始化蓝牙管理器
    2. 4.2. 4.2 连接到扫描的设备
    3. 4.3. 4.3 发送数据到设备
    4. 4.4. 4.4 设备中数据有更新
  5. 5. 5. 结论