如何在SwiftUI中实现后台蓝牙功能

4

我正在尝试在后台监听我的蓝牙设备,但好像没有任何反应。我尝试按照这里的指南进行操作,并对其进行了 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)

我添加了恢复代理方法。当我再次运行应用程序时,该方法会被调用。

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

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

}

启动选项的步骤对我似乎不起作用。对我来说,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()
        }
    }
}

1
你所说的“在后台监听我的蓝牙设备”具体是什么意思?这可能有很多不同的含义。状态恢复通常不是最重要的部分。对于某些问题,它是必需的,但通常是在处理更基本的问题之后添加的。(除非有一些状态需要恢复,否则状态恢复不起作用。)你是如何启动连接的,以及你希望它如何工作? - Rob Napier
当我的应用程序处于前台时,恢复状态被调用,并且在 didDiscover 被调用时我自动连接到外设。当我的应用程序进入后台并且我打开蓝牙设备时,没有任何内容被调用。 - Berry Blue
1
有代码示例吗?当应用程序进入后台以便在应用程序进入后台时发现已打开的BLE设备时,我不知道该做什么。 - Berry Blue
那么,如果我无法发现设备,当我处于后台时,如何知道它何时打开? - Berry Blue
1
当您处于前台时,可以调用“connect”进行连接。当设备被打开(即使在后台),操作系统也会建立连接,并唤醒或启动您的应用程序。一旦发现它,您就不需要再扫描它,而且确实不应该这样做。连接请求永远不会超时。关键是您在前台时调用“connect”。 - Rob Napier
显示剩余11条评论
1个回答

4
一旦你知道了设备的peripheralID,无论它是否连接,你都可以随时使用retrievePeripherals(withIdentifiers:)获取CBPeripheral。如果没有连接,只需调用connect发起连接请求即可。一旦你已经看到了设备,就没有必要再次扫描它(这是不鼓励的,因为扫描过程缓慢且耗电)。
连接请求不会超时。当应用程序进入后台时,请求仍将继续。即使应用程序被终止或设备被重新启动,请求也将继续。连接请求可以持续数周,完全没有问题,而且很省电。
当设备开机并处于范围内并且可连接时,操作系统将处理连接。然后,它将在后台将控制权交给您的应用程序,或者使用状态恢复启动您的应用程序。此时,您可以对已连接的设备进行任何操作。

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