You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI集成DJI UX SDK 5(Beta 0.4.1)时Widget连接状态异常问题求助

分析与解决方案:DJI UX SDK 5 Beta + SwiftUI 连接状态异常问题

这问题我之前折腾DJI SDK和SwiftUI混合开发时也碰到过类似的,结合你的描述和几次测试观察,核心大概率是Widget状态没有和SDK的实时连接状态同步,尤其是非Xcode启动场景下,Widget初始化时机晚于SDK连接完成的情况。咱们一步步排查解决:

1. 强制Widget同步SDK状态(最可能解决问题)

DUXBeta的Widget依赖SDK通知更新UI,但如果Widget初始化时SDK已经完成连接(比如手动启动应用时,SDK可能在后台已和设备连上),Widget就会错过连接通知,导致UI停留在初始状态。

修改BetaViewController,在viewDidAppear里手动触发Widget更新,同时订阅SDK连接通知确保后续状态变化能同步:

class BetaViewController<T: DUXBetaBaseWidget> : UIViewController {
    var djiWidget = T()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        addChild(djiWidget)
        djiWidget.install(in: self)
        makeConstraints()
    }
    
    func makeConstraints() {
        NSLayoutConstraint.activate([
            djiWidget.view.topAnchor.constraint(equalTo: view.topAnchor),
            djiWidget.view.bottomAnchor.constraint(equalTo: view.bottomAnchor),
            djiWidget.view.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            djiWidget.view.trailingAnchor.constraint(equalTo: view.trailingAnchor)
        ])
    }
    
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        // 手动触发Widget刷新当前状态
        djiWidget.update()
        // 订阅SDK连接/断开通知,确保状态变化同步到Widget
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(onProductStateChanged(_:)),
            name: NSNotification.Name(DJISDKManagerProductConnectedNotification),
            object: nil
        )
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(onProductStateChanged(_:)),
            name: NSNotification.Name(DJISDKManagerProductDisconnectedNotification),
            object: nil
        )
    }
    
    @objc func onProductStateChanged(_ notification: Notification) {
        DispatchQueue.main.async {
            self.djiWidget.update()
        }
    }
    
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        // 移除观察者避免内存泄漏
        NotificationCenter.default.removeObserver(self)
    }
}

同时在BetaDjiView的updateUIViewController里加一句更新,确保SwiftUI刷新时Widget同步状态:

struct BetaDjiView<DjiWidget: DUXBetaBaseWidget>: UIViewControllerRepresentable {
    typealias UIViewControllerType = BetaViewController<DjiWidget>
    
    func makeUIViewController(context: Context) -> BetaViewController<DjiWidget> {
        return BetaViewController<DjiWidget>()
    }
    
    func updateUIViewController(_ uiViewController: BetaViewController<DjiWidget>, context: Context) {
        uiViewController.djiWidget.update()
    }
}

2. 确保SDK初始化与权限时机正确

你提到删除重装后第一次启动权限请求后无响应、第二次才正常,说明权限授予后SDK没有重新触发设备连接检查。建议把SDK初始化放到App入口处,确保应用启动时完成注册,并在权限授予后主动扫描设备:

如果是纯SwiftUI App,修改@main结构体:

@main
struct DjiMobileSdkTest2App: App {
    init() {
        // 初始化DJI SDK
        DJISDKManager.registerApp(with: nil, delegate: AppDelegate())
    }
    
    var body: some Scene {
        WindowGroup {
            ContentView()
                .onAppear {
                    // 权限授予后,主动检查当前产品连接状态
                    if let product = DJISDKManager.product() {
                        NotificationCenter.default.post(
                            name: NSNotification.Name(DJISDKManagerProductConnectedNotification),
                            object: product
                        )
                    }
                }
        }
    }
}

class AppDelegate: NSObject, DJISDKManagerDelegate {
    func appRegisteredWithError(_ error: Error?) {
        if let error = error {
            print("SDK注册失败: \(error.localizedDescription)")
        } else {
            // 启动设备连接
            DJISDKManager.startConnectionToProduct()
        }
    }
    
    func productConnected(_ product: DJIBaseProduct) {
        print("产品已连接")
        // 发送通知让所有Widget同步状态
        NotificationCenter.default.post(
            name: NSNotification.Name(DJISDKManagerProductConnectedNotification),
            object: product
        )
    }
    
    func productDisconnected() {
        print("产品已断开")
        NotificationCenter.default.post(
            name: NSNotification.Name(DJISDKManagerProductDisconnectedNotification),
            object: nil
        )
    }
}

3. 排查Podfile配置与SDK加载问题

你的Podfile里手动设置了ARCHS = '$(ARCHS_STANDARD)',DJI SDK本身已适配标准架构,手动指定可能导致部分设备上的加载延迟,尝试移除该配置:

platform :ios, '11.0'
target 'DjiMobileSdkTest2' do
  use_frameworks!
  pod 'iOS-Color-Picker'
  pod 'DJI-UXSDK-iOS-Beta', '0.4.1'
end
post_install do |installer|
  installer.pods_project.targets.each do |target|
    target.build_configurations.each do |configuration|
      # 移除手动ARCHS设置
      # target.build_settings(configuration.name)['ARCHS'] = '$(ARCHS_STANDARD)'
    end
  end
end

为什么重启手机后正常?

重启手机后,系统会重置DJI SDK的后台状态,应用启动时SDK和Widget初始化同步,Widget能正常接收连接通知,所以UI正确更新。而手动启动应用时,SDK可能已在后台保持连接状态,Widget初始化晚了一步,没拿到这个状态。

按上面步骤修改后,应该能解决不同启动方式下的状态不同步问题。

内容的提问来源于stack exchange,提问作者Tobias

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 14:37:49