[英]Want to run Advertising peripheral in background mode iOS Swift
我只是用服务和特征 UUID 创建我的广告外围设备
这是我的服务和特征 UUID
let kTRANSFER_SERVICE_UUID = “29ada058-c7d6-4ed5-bc7f-1c7b0458b3b8”
let kTRANSFER_CHARACTERISTIC_UUID = “91e032f2-c915-47c6-a8d9-6b3bc6c8e73d”
现在我创建 CBPeripheralManager 的实例
private var peripheralManager: CBPeripheralManager!
private let beaconOperationsQueue = DispatchQueue(label: "beacon_operations_queue")
private let option = [CBCentralManagerScanOptionAllowDuplicatesKey:true]
// Assign peripheralManager with Queue & Option
peripheralManager = CBPeripheralManager(delegate: self, queue: beaconOperationsQueue, options: option)
然后我调用这个 StartAdvertising 方法,但这只会在前台模式下工作,现在我想在后台模式下允许,所以我在 Info.plist 中添加 UIBackgroundModes 键
public func startAdvertising(serviceID: String, name: String) {
let valueData = name.data(using: .utf8)
self.serviceID = CBUUID(string: serviceID)
self.peripheralName = name
let CustomChar = CBMutableCharacteristic(type: CBUUID(string: kTRANSFER_CHARACTERISTIC_UUID), properties: [.read], value: valueData, permissions: [.readable])
let myService = CBMutableService(type: self.serviceID, primary: true)
myService.characteristics = [CustomChar]
peripheralManager.add(myService)
if self.peripheralManager.isAdvertising{
self.peripheralManager.stopAdvertising()
}
peripheralManager.startAdvertising([
CBAdvertisementDataServiceUUIDsKey: [serviceID],
CBAdvertisementDataOverflowServiceUUIDsKey:[serviceID],
CBAdvertisementDataLocalNameKey: peripheralName!])
}
因此,当移动到后台时,会发生这种情况
CBAdvertisementDataLocalNameKey 广告键被忽略,并且外围设备的本地名称不被广告。
CBAdvertisementDataServiceUUIDsKey 广告键值中包含的所有服务 UUID 都放置在一个特殊的“溢出”区域; 它们只能被明确扫描它们的 iOS 设备发现。
我也被设置为“溢出”但仍然无法在后台模式下工作,
任何人都可以指导相同
当应用程序在后台时,Apple 对 CoreBluetooth 广告和扫描的工作方式施加了限制。 不幸的是,这种行为很复杂。 请多多包涵。
出于本讨论的目的,背景是指应用程序在屏幕上不可见的任何情况。 (手机锁定、屏幕关闭、显示跳板、显示另一个应用程序都是应用程序在后台的所有情况。)
CBPeripheralManager GATT 服务广告
0b ff 4c 00 10 06 57 1e fc 8a e1 7c
。 无论是在前台启动广告并将应用程序移至后台,还是在后台启动广告都无关紧要。 当广告 BLE 应用程序在后台时,此广告使用此专有格式。CBAdvertisementDataServiceUUIDsKey
中有什么内容,它都不会出现在广告中。CBAdvertisementDataLocalNameKey
中有什么内容,它都不会出现在广告中。CBAdvertisementDataServiceUUIDsKey
仅与其他 iOS 设备进行通信,并使用 CBCentralManager 进行前台应用程序CBCentralManager
。 这使用 Apple 专有技术。 实际服务UUIDS仅由iOS在有前台iOS应用扫描时应操作系统请求在“溢出区”提供。 如果没有前景的 iOS 应用程序扫描,这将不起作用,因为永远不会从“溢出区域”请求实际的服务 UUID。CBCentralManager GATT 服务扫描
在后台,不指定服务 UUID 的扫描不会产生任何结果。 如果你有这样的代码: centralManager?.scanForPeripherals(withServices: nil, options: nil)
,什么都不会匹配。 您必须明确指定服务 UUID。
由于CBCentralManagerScanOptionAllowDuplicatesKey
选项在后台被忽略,因此尝试从同一设备请求多个广告的回调将一无所获。 您只会在设备第一次出现时收到一个回调。
仅当广告设备不是后台 iOS 应用程序时,根据上述限制,扫描特定服务 UUID 最多会成功一次回调。
如果广告设备是后台 iOS 应用程序,则广告将使用上述专有技术。 由于中央在后台,iOS 不会向后台外围请求溢出区域。 不会发生发现回调。
那么最终结果是iOS 到 iOS GATT 广告和发现仅在两个蓝牙应用程序之一处于前台时才有效。 如果两个应用程序都在后台,则新发现将不起作用。 但是,当两个应用程序都在后台时,现有连接将继续工作并重新连接,如果设备消失并重新出现,将提供新的发现回调。 关键是当两个应用程序之一在前台时,发现必须成功一次。
为使上述操作生效,您无需在开始广告时设置CBAdvertisementDataOverflowServiceUUIDsKey
。 如果广告应用程序在后台,Apple 会自动将键CBAdvertisementDataServiceUUIDsKey
的任何值放入溢出区域。 CBAdvertisementDataOverflowServiceUUIDsKey
是只读的——您可以在收到扫描结果后访问此信息。 广告时不要使用它。
有趣的注意事项:在这种情况下,当您有两个以上的 iOS 设备时,如果在前台有第三个 iOS 应用程序扫描作为中心,那么当两者都在后台时,中央和外围设备可以相互发现。 然后,第三个 iOS 设备可以发出“溢出区域”的请求,从而允许后台 iOS 设备监听这一点并通过窃听受益。
Android 或其他非 iOS 设备可以扫描上述专有的 iOS 广告,虽然它们看不到服务 UUID 或从“溢出区域”请求它们,但它们仍然可以连接,然后查询连接内的服务 UUID。 这是低效的,但它可以工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.