Xcode 11向下兼容性:「UIWindowScene仅在iOS 13或更高版本中可用」。

82
在Xcode 11中,我创建了一个从单视图应用程序模板的新应用程序项目。我想让这个应用程序可以在iOS 12和iOS 13上运行。但是当我将部署目标切换到iOS 12时,我遇到了很多类似于以下错误消息:

UIWindowScene仅在iOS 13或更高版本中可用

我该怎么办?


6
如果有人正在寻找一个更新的“Single View App” Xcode模板,该模板支持iOS 12和13,并支持故事板或全代码用户界面,请访问https://github.com/rmaddy/XcodeTemplates。 - rmaddy
2个回答

108

Xcode 11的模板使用场景代理。场景代理及相关类是iOS 13中新增的,而在iOS 12及之前并不存在,启动过程也不同。

要使从Xcode 11应用程序模板生成的项目向后兼容,您需要标记整个SceneDelegate类以及任何引用UISceneSession的AppDelegate类中的方法为@available(iOS 13.0, *)

您还需要在AppDelegate类中声明一个window属性(如果不这样做,应用程序将运行和启动,但屏幕将是黑色的):

var window : UIWindow?

结果是,当这个应用在iOS 13上运行时,场景代理有window,但在运行iOS 12或更早版本时,应用代理有window —— 因此你的其他代码可能需要考虑到这一点才能向后兼容。


5
你的解决方案很好。话虽如此,如果你的唯一目标是支持iOS 12,是否直接删除“SceneDelegate”会更有意义呢?当然,将“var window:UIWindow?”添加回“AppDelegate”仍然是必要的。为了修复其他错误,你还需要从“AppDelegate”中删除生成的“UISceneSession Lifecycle”方法以及从“Info.plist”中删除“UIApplicationSceneManifest”键/值。或许保留“SceneDelegate”的其他原因,但可能性较小。 - JWK
1
我看到了来自224会议的2020年4月要求。我认为它与制作支持分屏多任务处理的自适应应用有关,而不是明确要求多重复制支持。也许我误解了。 - JWK
2
当然,我只是想确认我在哪里能够了解更多关于需要场景的内容。2020年4月的要求让我想起了我在WWDC上观看的内容。并不是想暗示您说的就是这个 :) - JWK
12
这篇教程可能对某些人有所帮助。链接为:https://sarunw.com/tips/create-new-ios12-project-in-xcode11/ - onCompletion
你能否提供一个在UISceneSession中使用@available(iOS 13.0, *)的示例? - user7396942
显示剩余5条评论

62

请您将以下代码行添加到如下位置:

步骤1:-

@available(outside of SceneDelegate.swift)

@available(iOS 13.0, *)
class SceneDelegate: UIResponder, UIWindowSceneDelegate {

//...

}

步骤2:-

在AppDelegate.swift中提供一些可用的方法

// AppDelegate.swift

@available(iOS 13.0, *)
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
    // Called when a new scene session is being created.
    // Use this method to select a configuration to create the new scene with.
    return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
}

@available(iOS 13.0, *)
func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
    // Called when the user discards a scene session.
    // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
    // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
}

步骤3:

您应该在AppDelegate.swift文件中声明 window 属性,例如 var window: UIWindow?

class AppDelegate: UIResponder, UIApplicationDelegate {

     var window: UIWindow?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        return true
    }

但是如果没有使用Storyboard,这将如何在编程实现中工作? - Hattori Hanzō
1
@HattoriHanzō 没有故事板:我们可以在AppDelegate中声明:var window: UIWindow? var rootViewController: ViewController!然后在didFinishLaunching方法中添加以下代码: rootViewController = ViewController() self.window = UIWindow.init() self.window?.bounds = UIScreen.main.bounds self.window?.rootViewController = rootViewController self.window?.backgroundColor = .white self.window?.makeKeyAndVisible() - Dilip Saket

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