【问题标题】:Migrating old Xcode project to new one with UISceneDelegate使用 UISceneDelegate 将旧 Xcode 项目迁移到新项目
【发布时间】:2020-12-04 23:03:39
【问题描述】:

我有一个没有 UISceneDelegate 方法的旧 Xcode 项目。是否可以使用 UISceneDelegate 方法将旧 Xcode 项目迁移到新项目,但仍保持与 iOS 12 的兼容性?

如果是这样,怎么做?因为我在 iOS 14 中看到了很多错误,唯一的解决方法是使用 UISceneDelegate 方法。

【问题讨论】:

    标签: ios xcode uiapplication uiscenedelegate


    【解决方案1】:

    编辑 1:

    确保在 View Controller 的视图呈现后查询 windowOrientation。通常在viewDidLoad()viewWillAppear(_:) 中,view.windownil,请检查此answer。只需检查 viewDidAppear(_:)windowOrientation 的值即可。

    如果您在尝试以下定义之前访问此值时遇到问题

    private var windowOrientation: UIInterfaceOrientation {
        if #available(iOS 13.0, *) {
            return UIApplication.shared.windows.first?.windowScene?.interfaceOrientation ?? .unknown
        } else {
            // Fallback on earlier versions
            return UIApplication.shared.statusBarOrientation
        }
    }
    

    我不确定您的应用是否使用多个窗口,但如果只有一个(因为您没有以编程方式创建任何窗口),以下定义应该可以正常工作。

    var hasTopNotch: Bool {
        return UIApplication.shared.windows.first?.safeAreaInsets.top ?? 0 > 20
    }
    

    原答案:

    UISceneDelegate已经在iOS 13.0中引入,所以无法兼容iOS 12,需要完全依赖UIApplicationDelegate。要支持UISceneDelegate 中的iOS 13.x,您需要添加显式可用性检查以避免编译错误。

    步骤 1:在Info.plist 中添加场景清单

    打开Info.plistSource Code并添加以下内容

    <key>UIApplicationSceneManifest</key>
    <dict>
        <key>UIApplicationSupportsMultipleScenes</key>
        <false/>
        <key>UISceneConfigurations</key>
        <dict>
            <key>UIWindowSceneSessionRoleApplication</key>
            <array>
                <dict>
                    <key>UISceneConfigurationName</key>
                    <string>Default Configuration</string>
                    <key>UISceneDelegateClassName</key>
                    <string>$(PRODUCT_MODULE_NAME).SceneDelegate</string>
                    <key>UISceneStoryboardFile</key>
                    <string>Main</string>
                </dict>
            </array>
        </dict>
    </dict>
    

    第二步:创建SceneDelegate.swift文件,内容如下

    import UIKit
    @available(iOS 13.0, *)
    class SceneDelegate: UIResponder, UIWindowSceneDelegate {
    
        var window: UIWindow?
    
    
        func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
            // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
            // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
            // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
            guard let _ = (scene as? UIWindowScene) else { return }
        }
    
        func sceneDidDisconnect(_ scene: UIScene) {
            // Called as the scene is being released by the system.
            // This occurs shortly after the scene enters the background, or when its session is discarded.
            // Release any resources associated with this scene that can be re-created the next time the scene connects.
            // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead).
        }
    
        func sceneDidBecomeActive(_ scene: UIScene) {
            // Called when the scene has moved from an inactive state to an active state.
            // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
        }
    
        func sceneWillResignActive(_ scene: UIScene) {
            // Called when the scene will move from an active state to an inactive state.
            // This may occur due to temporary interruptions (ex. an incoming phone call).
        }
    
        func sceneWillEnterForeground(_ scene: UIScene) {
            // Called as the scene transitions from the background to the foreground.
            // Use this method to undo the changes made on entering the background.
        }
    
        func sceneDidEnterBackground(_ scene: UIScene) {
            // Called as the scene transitions from the foreground to the background.
            // Use this method to save data, release shared resources, and store enough scene-specific state information
            // to restore the scene back to its current state.
        }
    
    
    }
    

    第三步:更新AppDelegate

    1. 添加 UISceneSession Lifecycle 方法。
    // MARK: UISceneSession Lifecycle
    @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.
    }
    

    ii) 最后参考Apple Documentation。您可以参考https://dev.to/kevinmaarek/add-a-scene-delegate-to-your-current-project-5on 了解更多清理和设置任务。

    【讨论】:

    • 查看代码,我相信这段代码应该可以在 iOS 13 及更高版本上运行,最重要的是不会对运行 iOS12 的设备产生任何影响,对吗?
    • impact anything on devices running iOS12, correct 很抱歉,我没有运行 iOS 12.x 的设备,因为您的目标是它,我猜您有。请在真实设备上对其进行测试,以使其能够投入生产。
    • view.window?.windowScene?添加代码后结果为零。有什么我想补充的吗?
    • 其实view.window加载后在rootViewController中为nil。
    • 你能在func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) 中设置一个断点并运行po window 吗? iOS13.0 应该有一些价值,而在 AppDelegate 的 didFinishLaunchingWithOptions 中应该是 nil
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-04-08
    • 1970-01-01
    • 2012-03-02
    • 1970-01-01
    • 2019-10-24
    • 2019-07-21
    • 1970-01-01
    相关资源
    最近更新 更多