繁体   English   中英

想要在后台模式下运行广告外设 iOS Swift

[英]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 服务广告

  • 在后台,服务广告更改为 Apple 专有格式,该格式使用如下所示的制造商广告: 0b ff 4c 00 10 06 57 1e fc 8a e1 7c 无论是在前台启动广告并将应用程序移至后台,还是在后台启动广告都无关紧要。 当广告 BLE 应用程序在后台时,此广告使用此专有格式。
  • 上述广告不包含服务 UUID。 无论CBAdvertisementDataServiceUUIDsKey中有什么内容,它都不会出现在广告中。
  • 上述广告不包含本地名称。 无论CBAdvertisementDataLocalNameKey中有什么内容,它都不会出现在广告中。
  • 此广告用于将指定的服务 UUID 从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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM