简体   繁体   English

SwiftUI AppDelegate 在打开应用程序时不会运行

[英]SwiftUI AppDelegate not being ran whenever app is opened

Here is a simple AppDelegate that I have made:这是我制作的一个简单的AppDelegate

import SwiftUI

class AppDelegate: UIResponder, UIApplicationDelegate {

    private func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -> Bool {
        print("application")
        // first launch
        // this method is called only on first launch when app was closed / killed
        return true
    }

    private func applicationWillEnterForeground(application: UIApplication) -> Bool{
        print("applicationWillEnterForeground")
        // app will enter in foreground
        // this method is called on first launch when app was closed / killed and every time app is reopened or change status from background to foreground (ex. mobile call)
        return true
    }

    private func applicationDidBecomeActive(application: UIApplication) -> Bool {
        print("applicationDidBecomeActive")
        // app becomes active
        // this method is called on first launch when app was closed / killed and every time app is reopened or change status from background to foreground (ex. mobile call)
        return true
    }
}

@main
struct CouponDeckApp: App {
    @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
    @Environment(\.scenePhase) private var scenePhase
    var body: some Scene {
        WindowGroup {
            AppContentView()
                
        }
    }
}

The AppDelegate doesn't seem to be calling any of its functions, though.不过, AppDelegate似乎没有调用它的任何函数。 It should be running them at 3 places, but none are running.它应该在 3 个地方运行它们,但没有一个在运行。 Why is this happening, and how do I fix it?为什么会发生这种情况,我该如何解决?

You've marked your app with @main which makes it app entry point.您已使用@main标记了您的应用程序,这使其成为应用程序入口点。

Not all methods of app delegate will work with UIApplicationDelegateAdaptor , like here applicationWillEnterForeground applicationDidBecomeActive won't be called.并非所有应用程序委托的方法都可以与UIApplicationDelegateAdaptor一起使用,就像这里的applicationWillEnterForeground applicationDidBecomeActive不会被调用。

Instead you're supposed to use publishers inside SwiftUI view, like this:相反,您应该在 SwiftUI 视图中使用发布者,如下所示:

.onReceive(NotificationCenter.default.publisher(for: UIApplication.didBecomeActiveNotification)) { _ in
    print("applicationDidBecomeActive")
}
.onReceive(NotificationCenter.default.publisher(for: UIApplication.willEnterForegroundNotification)) { _ in
    print("applicationWillEnterForeground")
}

An other problem with your AppDelegate is that it doesn't have needed methods signature. AppDelegate的另一个问题是它没有所需的方法签名。 When you're adding new method, don't paste it from somewhere, instead type a couple of letters from method name and let Xcode finish the rest.添加新方法时,不要从某处粘贴,而是从方法名称中键入几个字母,然后让 Xcode 完成 rest。 In your case if you have your signature correct, private would be an error reported by Xcode.在您的情况下,如果您的签名正确,则private将是 Xcode 报告的错误。

If you still wanna get them inside your delegate for some reason, you need to move @main to AppDelegate , and initialize your SwiftUI view with UIHostingController like it was back done in SwiftUI 1:如果您出于某种原因仍想将它们放入您的委托中,则需要将@main移动到AppDelegate ,并使用UIHostingController初始化您的 SwiftUI 视图,就像在 SwiftUI 1 中所做的那样:

@main
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?
    
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        let window = UIWindow()
        self.window = window
        window.rootViewController = UIHostingController(rootView: ContentView())
        window.makeKeyAndVisible()
        return true
    }
    
    func applicationWillEnterForeground(_ application: UIApplication) {
        print("applicationWillEnterForeground")
    }
    
    func applicationDidBecomeActive(_ application: UIApplication) {
        print("applicationDidBecomeActive")
    }
}

Also you need to update Info.plist , set enable multiple windows to NO :您还需要更新Info.plist ,将启用多个 windows 设置为NO

Use the SceneDelegate file instead.请改用 SceneDelegate 文件。

Add it in this method:在这个方法中添加它:

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { } func场景(_场景:UIScene,willConnectTo session:UISceneSession,选项connectionOptions:UIScene.ConnectionOptions){}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM