无法将 SwiftUI.ExtensionDelegate 转换为 ExtensionDelegate

Couldn't cast SwiftUI.ExtensionDelegate to ExtensionDelegate

使用 SwiftUI Architecture WatchOS 应用程序,如果您想使用 ExtensionDelegate,则需要创建自己的。我已经这样做了,但是当我尝试实际访问代码中的委托时,我收到以下错误消息 Could not cast value of type SwiftUI.ExtensionDelegate' (0x7fff8441b480) to 'TestMe_WatchKit_Extension.ExtensionDelegate' (0x10c3b36d0).
我已将 ExtensionDelegate 定义为 -

class ExtensionDelegate: NSObject, WKExtensionDelegate {
    var meetingStatistics:  MeetingStatistics = MeetingStatistics()
    override init(){
        super.init()
    }
    func applicationDidFinishLaunching() {
        // Perform any final initialization of your application.
        print("applicationDidFinishLaunching for watchOS")
    }
    func applicationDidBecomeActive() {
        // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
    }
    func applicationWillResignActive() {
        // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
        // Use this method to pause ongoing tasks, disable timers, etc.
    }
}

在我的@main - 我有以下内容:

@main
struct WatchApp: App {
@WKExtensionDelegateAdaptor(ExtensionDelegate.self) var delegate
// code

}

当我尝试访问委托时 - let delegate = WKExtension.shared().delegate as! ExtensionDelegate 我收到上面的错误。

WKExtension.shared().delegate 不是您的 ExtensionDelegate 而是 internal SwiftUI.ExtensionDelegate(如所述),它提供您的适配器 delegate.您必须使用(到处传递) 为您的 via

提供的适配器委托实例
@WKExtensionDelegateAdaptor(ExtensionDelegate.self) var delegate

更新:

要使用你的 delegate 你必须将它作为参数传递给视图,例如作为环境(这样你就可以在任何子视图中使用它作为 @Environment(\.appDelegate) var appDelegate

var body: some Scene {
    WindowGroup {
       ContentView()
          .environment(\.appDelegate, delegate)
    }
}

struct DelegateKey: EnvironmentKey {
    typealias Value = ExtensionDelegate?
    static let defaultValue: ExtensionDelegate? = nil
}

extension EnvironmentValues {
    var appDelegate: DelegateKey.Value {
        get {
            return self[DelegateKey.self]
        }
        set {
            self[DelegateKey.self] = newValue
        }
    }
}

我在 macOS 中遇到了同样的问题。在将 class 声明为在 @main App 结构中使用的应用程序委托后:

@NSApplicationDelegateAdaptor(AppDelegate.self) var applicationDelegate

AppDelegate 在应用程序启动时正确初始化。 我声明环境密钥:

struct DelegateKey: EnvironmentKey {
    typealias Value = AppDelegate
    static let defaultValue: AppDelegate = AppDelegate()
}

extension EnvironmentValues {
    var appDelegate: DelegateKey.Value {
        get {
            return self[DelegateKey.self]
        }
        set {
            self[DelegateKey.self] = newValue
        }
    }
}

通过以下方式访问变量 @Environment(\.appDelegate) var appDelegate

这适用于所有 SwiftUI 环境。 问题是对应用程序委托的一般访问是通过 NSApp.delegate 不再工作了。

解决方法是在AppDelegateclass本身声明一个静态变量:

class AppDelegate: NSObject, NSApplicationDelegate, ObservableObject {
   
   @Environment(\.appDelegate) static var shared
}

这使得实例化的 AppDelegate 对象可以通过以下方式从任何地方访问: AppDelegate.shared .

嗯,- 同时我收集了更多的经验。对于我的应用程序委托,重要的是它是一个单例(只存在一个实例)。我意识到我有两个。

@NSApplicationDelegateAdaptor(AppDelegate.self) var applicationDelegate

在 SwiftUI App 结构中初始化第一个。我向这个 App 结构添加了一个 init() 方法。

 init() {
  
  AppDelegate.shared = self.applicationDelegate
}

这在程序的早期就初始化了我的 AppDelegate 静态变量“共享”。

我删除了所有基于@Environment 的委托访问、密钥、默认值等。全局访问由

确保
AppDelegate.shared

自定义@Environment 变量的问题在于,它们只能在视图上使用 .environment(_ keyPath:, _ value:) 修饰符进行设置。但是,在第一个视图设置环境变量之前访问了我的委托。因此,我的 AppDelegate 共享变量现在是我尽早设置的普通静态变量:在 App 结构的 init() 方法中。