如何在AppDelegate和SceneDelegate之间共享一个对象

3

我已经在使用AppDelegate来注册APNs,但是它不支持由SceneDelegate处理的applicationWillResignActive()applicationWillEnterForeground()函数,如这里所解释的。

我希望两个委托都能访问我的客户端实例。目前,AppDelegateclient实例化为其属性,然后将其作为environmentObject传递给场景:

import SwiftUI

@main
struct app1App: App {

  @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate

  var body: some Scene {
    WindowGroup {
      MainView().environmentObject(appDelegate.client)
    }
  }
}

class AppDelegate: NSObject, UIApplicationDelegate {
  
  let client : Client = Client()
  // other Notifications related functions
}

当我在视图中声明我的客户端时,如下所示:
@EnvironmentObject var client: Client

如果我在视图中声明,则视图可以访问客户端的方法,但是当我在SceneDelegate中声明时,同样的方法不起作用:

class SceneDelegate: NSObject, UIWindowSceneDelegate {

  @EnvironmentObject var client: Client

  func sceneWillEnterForeground(_ scene: UIScene) {
    self.client.disconnect()  // This fails in runtime!!!
  }
}

错误提示说它期望一个Observable对象,但我的对象是environmentObject:
Thread 1: Fatal error: No ObservableObject of type Client found. A View.environmentObject(_:) for Client may be missing as an ancestor of this view.

如何通过SceneDelegate中的函数向客户端提供访问权限?


也许你只需要这个 https://dev59.com/fFIG5IYBdhLWcg3wzU2B#62840614?如果不是,那么可以按照这里所示的方式设置SceneDelegate https://dev59.com/nlIH5IYBdhLWcg3wQLfr#60359809。 - Asperi
@Asperi 差不多已经找到问题的根源了 - 问题已更新。只需要帮忙在两个委托之间共享客户端 - 有什么建议吗? - Nazar
1个回答

1

我只需要在两个委托之间共享客户端,你有什么建议吗?

如果要在整个应用程序中共享,则最简单的方法是将其设置为全局变量。

let client : Client = Client()    // << create here

class AppDelegate: NSObject, UIApplicationDelegate {
  // access `client` here directly
  // other Notifications related functions
}

class SceneDelegate: NSObject, UIWindowSceneDelegate {

  func sceneWillEnterForeground(_ scene: UIScene) {
    // access `client` here directly
    client.disconnect()  // This fails in runtime!!!
  }
}

我的AppDelegate和SceneDelegate位于不同的文件中。当我把let client : Client = Client()放在struct app1App: App {}之外的@main下面(就像在C语言中声明全局变量一样),编译器会报错,提示“@main”属性不能应用于该声明。那么在我的情况下,它应该放在哪里?它仍然应该是一个_environmetObject_以便被视图访问和监视吗? - Nazar
将全局定义放在 @main 之上解决了问题。 - Nazar

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