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

如何在AppDelegate中访问EnvironmentObject?Watch Connectivity问题排查

问题原因分析
  • @EnvironmentObject 是SwiftUI专为View层级内组件设计的依赖注入方式,AppDelegate属于UIKit代理类,不在SwiftUI的View树结构中,因此无法通过@EnvironmentObject获取CameraManager实例,直接访问会触发崩溃。
  • 你在App入口设置的environmentObject(cameraManager)仅对SwiftUI的View层级生效,AppDelegate不在这个环境范围内,自然拿不到对应实例。
修复方案

步骤1:修改AppDelegate,移除@EnvironmentObject改为直接持有引用

class AppDelegate:NSObject, UIApplicationDelegate, WCSessionDelegate {
    
    // 替换@EnvironmentObject为可选属性
    var cameraManager: CameraManager?
    
    func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {
        
    }
    
    func sessionDidBecomeInactive(_ session: WCSession) {
        
    }
    
    func sessionDidDeactivate(_ session: WCSession) {
        
    }
    
    func session(_ session: WCSession, didReceiveMessage message: [String : Any], replyHandler: @escaping ([String : Any]) -> Void) {
        guard let request = message["request"] as? String else {
            replyHandler([:])
            return
        }
        switch request {
        case "test":
            replyHandler(["test":"Success"])
        case "optionSelected":
            replyHandler(["optionSelected":"Success"])
            // 切换到主线程修改@Published属性,避免UI更新异常
            DispatchQueue.main.async {
                self.cameraManager?.isOptionSelected = true
            }
        default:
            replyHandler([:])
        }
    }

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
        if WCSession.isSupported() {
            let session = WCSession.default
            session.delegate = self
            session.activate()
        }
        return true
    }
}

步骤2:在App入口传递CameraManager实例给AppDelegate

@main
struct AppName: App {
    
    @StateObject var cameraManager = CameraManager()
    
    @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
    
    // 初始化时传递实例,保证二者共用同一个CameraManager
    init() {
        appDelegate.cameraManager = cameraManager
    }
    
    var body: some Scene {
        WindowGroup {
            NavigationView {
                ContentView()
            }
            .environmentObject(cameraManager)
        }
    }
}

补充说明

  • 主线程修改要求:WCSession回调运行在后台线程,而SwiftUI的UI更新依赖主线程,必须用DispatchQueue.main.async包裹属性修改操作,避免UI异常。
  • 可选链保护:用cameraManager?.isOptionSelected可以防止AppDelegate未拿到实例时出现nil崩溃,提升代码健壮性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 16:40:26