最近在研究 Tuist,一个用来管理 Xcode 项目的工具。这个工具好像从 4.0 版本开始,创建新项目默认就是 SwiftUI 模版了,所以需要手动再从 SwiftUI 改回 UIKit。

在改动过程中发现 SceneDelegate 不执行,搜索了一番后找到了解决方案,在此记录一下。

具体的改动方法和流程可以参考:How to migrate from SwiftUI to UIKit App Delegate Life Cycle in Xcode

解决方案出自这里:App migrated to UIKit lifecycle doesn't call SceneDelegate

插一嘴,真没想到还会有其他人也遇到了这个问题...

如上述问题里所讲的那样,这个 bug 的根本问题可能是:

do not turn off support multiple windows. It seems that disabling multiple windows prevents UIKit from launching a new scene when the previous scene is no longer available.

也就是说 SwiftUI 的 @main 入口没了,同时因为不支持多窗口,所以导致在当前场景不可用时,无法创建 SceneDelegate 的新场景。

解决方案除了把设备上的 app 删除重新安装之外,还可以把 Info.plist 中的 scene configurations manifest 删除,然后手动创建它:

class AppDelegate: NSObject, UIApplicationDelegate {
    func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
        let configuration = UISceneConfiguration(name: nil, sessionRole: connectingSceneSession.role)
        if connectingSceneSession.role == .windowApplication {
            configuration.delegateClass = SceneDelegate.self
        }
        return configuration
    }
}

注意,如果不删那么这个方法也是不会调用的,所以需要删除然后手动创建。

最后吐槽一下,真的没想到 iOS 就连这个也会有类似 “缓存” 的问题... 想到了 LaunchScreen ...