在后台启动Swift线程

4
我将尝试使用以下代码在后台线程中发送进程:

``` 我想使用以下代码在后台线程中发送进程: ```

let qualityOfServiceClass = QOS_CLASS_BACKGROUND
let backgroundQueue = dispatch_get_global_queue(qualityOfServiceClass, 0)

dispatch_async(backgroundQueue, {
    print("running in the background queue")
    btDiscovery
})

但是该类仅在前台处理时才会执行...有什么想法吗?

编辑1:

btDiscovery是一个类,每X秒执行一次BLE设备扫描:

let btDiscoverySharedInstance = Beacon();

class Beacon: NSObject, CBCentralManagerDelegate {

private var centralManager: CBCentralManager?
private var peripheralBLE: CBPeripheral?
....


   func centralManagerDidUpdateState(central: CBCentralManager) {
    switch (central.state) {
    case CBCentralManagerState.PoweredOff:
        print("BLE powered off")
        self.clearDevices()

    case CBCentralManagerState.Unauthorized:
        // Indicate to user that the iOS device does not support BLE.
        print("BLE not supported")
        break

    case CBCentralManagerState.Unknown:
        // Wait for another event
        print("BLE unknown event")
        break

    case CBCentralManagerState.PoweredOn:
        print("BLE powered on")
            self.startScanning()
        break

    case CBCentralManagerState.Resetting:
        print("BLE reset")
        self.clearDevices()

    case CBCentralManagerState.Unsupported:
        print("BLE unsupported event")
        break
    }
}


    func startScanning() {
    print("Start scanning...")
        if let central = centralManager {
            central.scanForPeripheralsWithServices(nil, options: nil)
        }
    }

  func centralManager(central: CBCentralManager, didDiscoverPeripheral peripheral: CBPeripheral, advertisementData: [String : AnyObject], RSSI: NSNumber) {
    print("Discovered peripheral \(RSSI) dBM name: \(peripheral.name)")
    print("UUID: \(peripheral.identifier.UUIDString)")
    ...
    sleep(delayPolling)
    self.startScanning()
  }

当应用程序启动并保持在前台时,扫描每"delayPolling"秒会正确执行。但是,一旦我将我的应用程序置于后台,扫描就会暂停。它只有在再次回到前台时才重新启动。

我需要让此扫描在后台始终运行(即使我们为此线程设置较低的优先级)。

编辑2:

通过阅读文档https://developer.apple.com/library/ios/documentation/NetworkingInternetWeb/Conceptual/CoreBluetooth_concepts/CoreBluetoothBackgroundProcessingForIOSApps/PerformingTasksWhileYourAppIsInTheBackground.html,我可以看到:

当实现中央角色的应用程序在其Info.plist文件中使用UIBackgroundModes密钥,并将值bluetooth-central与之配对时,Core Bluetooth框架允许您的应用程序在后台运行以执行某些与蓝牙相关的任务。当您的应用程序在后台运行时,仍然可以发现和连接外围设备,并探索和交互与外围数据。此外,当调用任何CBCentralManagerDelegate或CBPeripheralDelegate委托方法时,系统会唤醒您的应用程序

我在我的Info.plist文件中选择了相应的选项:

enter image description here

但是我的应用程序没有在后台运行我的线程。


什么是'while begin'?你怎么知道它在前台执行?尝试向块添加断点;调试器可以显示停在断点上时正在执行的线程和队列。 - Graham Perks
2
你的意思是当你的应用程序在后台运行时吗?这不是 iOS 上 QOS_CLASS_BACKGROUND 的意思。它只是表示一个较低优先级的队列,但它仍然只在你的应用程序在前台运行时执行。你能更清楚地解释一下你想做什么吗? - Paulw11
btDiscovery是一个执行BLE设备扫描的类。当我的应用程序在后台运行时,包含在btDiscovery类中的centralManagerDidUpdateState从未被调用。我将尝试使用调试器。在前台,扫描可以正确执行,但是一旦我将应用程序放到后台,扫描就会停止,并在应用程序回到前台时重新启动。 - tiamat
也许您需要更多的细节来帮助我吗? - tiamat
1个回答

3

我知道这是一个老问题,但在后台扫描需要提供服务UUID。

central.scanForPeripheralsWithServices(nil, options: nil)

需要进行
central.scanForPeripheralsWithServices(serviceUUID, options: nil)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接