今是昨非

今是昨非

日出江花红胜火,春来江水绿如蓝

iOS 新しく作成したプロジェクトからSceneDelegateを削除

iOS 新しく作成したプロジェクトから SceneDelegate を削除する#

背景#

Xcode 11 以降、新しいプロジェクトを作成すると、デフォルトで SceneDelegate が含まれていますが、SceneDelegate は iOS 13 以降に導入されたものです。もし最低互換バージョンが iOS 13 未満の場合、どうすればよいのでしょうか?

过程#

まず、SceneDelegate とは何か、なぜ SceneDelegate が必要なのかを見てみましょう。

公式説明:

UISceneSession オブジェクトは、シーンのユニークなランタイムインスタンスを管理します。ユーザーがアプリに新しいシーンを追加するか、プログラム的にリクエストすると、システムはそのシーンを追跡するためのセッションオブジェクトを作成します。セッションにはユニークな識別子とシーンの構成詳細が含まれています。UIKit はシーン自体のライフタイムにわたってセッション情報を維持し、ユーザーがアプリスイッチャーでシーンを閉じると、セッションを破棄します。
セッションオブジェクトを直接作成することはありません。UIKit は、アプリとのユーザーインタラクションに応じてセッションを作成します。また、UIApplication の requestSceneSessionActivation (_:userActivity:options:errorHandler:) メソッドを呼び出すことで、UIKit に新しいシーンとセッションをプログラム的に作成するように依頼することもできます。UIKit は、アプリの Info.plist ファイルの内容に基づいてデフォルトの構成データでセッションを初期化します。

翻訳説明:

iOS 13(以降)では、SceneDelegate が AppDelegate のいくつかの機能を担当します。最も重要なのは、ウィンドウの概念がシーンの概念に置き換えられたことです。アプリケーションは複数のシーンを持つことができ、シーンは現在、アプリケーションのユーザーインターフェースとコンテンツのコンテナ(背景)として機能します。

Xcode 11 で新しく作成されたプロジェクトで SceneDelegate に関連する部分は以下の通りです:

  1. AppDelegate クラス内の 2 つの「シーンセッション」メソッド:application (:configurationForConnecting:options:) と application (:didDiscardSceneSessions:)
  2. ライフサイクルイベント(active、resign、disconnect など)を含む SceneDelegate クラス。
  3. Info.plist ファイルに「Application Scene Manifest」構成項目が提供されており、アプリのシーンを構成するためのシーン構成名、delegate クラス名、storyboard エントリが含まれています。

SceneDelegate が不要な場合、どう処理すればよいのでしょうか?
2 つの方法があります。
a. SceneDelegate に関連するものを直接削除する
b. システムバージョンに基づいて互換性を判断する

方法一:SceneDelegate を削除する

  1. AppDelegate 内の UISceneSession Lifecycle の 2 つのデリゲートメソッドを削除し、window プロパティを追加し、application:didFinishLaunchingWithOptions: メソッド内で window を初期化し、ルートビューを設定します。
  2. SceneDelegate ファイルを削除します。
  3. ターゲットを選択し、info に切り替え、「Application Scene Manifest」行を削除します。

/// AppDelegate.Swift

import UIKit

@main
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // アプリケーション起動後のカスタマイズのためのオーバーライドポイント。
        
        self.window = UIWindow(frame: UIScreen.main.bounds)
        self.window?.backgroundColor = UIColor.white
        
        self.window?.rootViewController = HXBaseViewController()
        self.window?.makeKeyAndVisible()
        
        return true
    }

}

WeCom20210421-115403@2x.png

方法二:システムバージョンに基づいて互換性を判断しますが、この方法では注意が必要です。iOS 13 以降では、一部のプログラム状態の処理は SceneDelegate 内で行う必要があります。

  1. まず SceneDelegate に @available (iOS 13, *) の宣言を追加します。
  2. 次に、AppDelegate 内の UISceneSession Lifecycle の 2 つのデリゲートメソッドを別の Extension に書き、@available (iOS 13, *) を宣言します。
  3. AppDelegate の起動メソッドも変更する必要があり、コンパイルします。

// SceneDelegate.swift
import UIKit

@available(iOS 13, *)
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
    xxx
}


class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // アプリケーション起動後のカスタマイズのためのオーバーライドポイント。
        
        if #available(iOS 13.0, *) {
            // 処理は不要、SceneDelegateを使用
        }
        else {
            // UIWindowを初期化
            window = UIWindow.init()
            window?.frame = UIScreen.main.bounds
            window?.makeKeyAndVisible()
            window?.rootViewController = UIStoryboard.init(name: "Main", bundle: nil).instantiateInitialViewController()
        }
        return true
    }
}



@available(iOS 13, *)
extension AppDelegate {
    // MARK: UISceneSession Lifecycle

    func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
        // 新しいシーンセッションが作成されるときに呼び出されます。
        // このメソッドを使用して、新しいシーンを作成するための構成を選択します。
        return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
    }

    func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
        // ユーザーがシーンセッションを破棄したときに呼び出されます。
        // アプリケーションが実行されていない間にセッションが破棄された場合、application:didFinishLaunchingWithOptionsの直後に呼び出されます。
        // 破棄されたシーンに特有のリソースを解放するためにこのメソッドを使用します。
    }
}

参考#

iOS13 Scene Delegate の詳細
iOS 13 SceneDelegate の適応

読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。