SwiftUI中调用showBluetoothAccessoryPicker不显示蓝牙配件选择窗口怎么办
解决方案
核心原因
你声明了AppDelegate的window属性但未对其赋值,External Accessory框架无法找到承载配件选择弹窗的窗口容器,因此窗口无法正常弹出。
操作步骤
1. 检查基础配置
首先确认Info.plist中已添加如下配置:
UISupportedExternalAccessoryProtocols数组:填写你的目标配件对应的通信协议字符串,未配置该字段会导致配件无法被识别- 蓝牙权限描述:iOS 13及以上添加
NSBluetoothAlwaysUsageDescription,iOS 12及以下添加NSBluetoothPeripheralUsageDescription,未配置权限会导致弹窗被系统拦截
如果是Mac Catalyst应用,还需要在项目Signing & Capabilities中勾选External Accessory communication权限。
2. 修正AppDelegate实现
给window属性正确赋值,关联当前应用的活跃窗口:
class AppDelegate: NSObject, UIApplicationDelegate { var window: UIWindow? func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool { // 绑定当前活跃的key window到AppDelegate的window属性 window = UIApplication.shared.connectedScenes .filter { $0.activationState == .foregroundActive } .compactMap { $0 as? UIWindowScene } .first?.windows.first(where: \.isKeyWindow) return true } }
3. 调用配件选择器的示例代码
后续调用逻辑和UIKit侧完全一致,示例如下:
import ExternalAccessory func openAccessoryPicker() { let manager = EAAccessoryManager.shared() // withNameFilter可传入字符串过滤配件名称,predicate可自定义过滤规则,不需要的话传nil即可 manager.showBluetoothAccessoryPicker(withNameFilter: nil, predicate: nil) { error in if let error = error { // 处理错误,比如用户手动关闭了选择窗口 print("选择失败: \(error.localizedDescription)") return } // 选择成功后读取已连接的配件列表,后续连接逻辑和你之前UIKit侧的实现完全一致 guard let targetAccessory = manager.connectedAccessories.first else { return } // 执行配件连接、通信逻辑 } }
注意事项
不要在应用启动的早期生命周期(比如App初始化、onAppear刚触发时)调用选择器,要确保应用完全进入前台、根视图加载完成后再调用,避免窗口容器未生成导致弹出失败。
内容的提问来源于stack exchange,提问作者SBBG
相关产品推荐
相关产品推荐

