如何在 SwiftUI 中在后台进行蓝牙操作

Ber*_*lue 5 ios core-bluetooth ios-bluetooth swift swiftui

我试图在后台监听我的蓝牙设备,但似乎什么也没发生。我尝试按照此处的指南并针对 SwiftUI 进行修改。

https://developer.apple.com/library/archive/documentation/NetworkingInternetWeb/Conceptual/CoreBluetooth_concepts/CoreBluetoothBackgroundProcessingForIOSApps/PerformingTasksWhileYourAppIsInTheBackground.html

我启用了bluetooth-central后台模式。

我选择加入状态保护和恢复。

let options = [CBCentralManagerOptionRestoreIdentifierKey : "myCentralManagerIdentifier"]
centralManager = CBCentralManager(delegate: self, queue: nil, options: options)
Run Code Online (Sandbox Code Playgroud)

我添加了恢复委托方法。当我第一次再次运行该应用程序时,会调用此方法。

func centralManager(_ central: CBCentralManager, willRestoreState dict: [String : Any]) {

    guard let peripherals = dict[CBCentralManagerRestoredStatePeripheralsKey] as? [CBPeripheral] else {
        return
    }
    
    for peripheral in peripherals {
        // ...
    }

}
Run Code Online (Sandbox Code Playgroud)

启动选项的步骤似乎对我不起作用。字典launchOptions永远nil适合我。

import SwiftUI
import UIKit

class AppDelegate: NSObject, UIApplicationDelegate {
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
        guard let options = launchOptions else {
            return true
        }
        
        let centralManagerIdentifiers = options[UIApplication.LaunchOptionsKey.bluetoothCentrals]
        return true
    }
}

@main
struct MyApp: App {
    
    @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
    
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Rob*_*ier 4

一旦您知道设备的peripheralID,您就可以随时为其获取 CBPeripheral,retrievePeripherals(withIdentifiers:)无论其是否已连接。如果没有连接,你可以直接调用connect发起连接请求。一旦您以前见过它,就无需扫描它(不鼓励这样做,因为扫描速度慢且耗电)。

连接请求永远不会超时。当应用程序进入后台时,请求将继续。如果应用程序终止或设备重新启动,它甚至会继续。连接请求可能会运行数周。一切都很好,符合预期,而且电池效率很高。

当设备打开且在范围内且可连接时,操作系统将处理连接。然后,它将在后台手动控制您的应用程序,或者使用状态恢复启动您的应用程序。那时,您可以使用连接的设备做任何您想做的事情。