iosのAppDelegateは何なのか?
最初に
AppDelegate.swiftはswiftでIOSのnotification通知開発を始めてから見えて、ずっと気になってこの記事で簡単にまとめます。
AppDelegateとは?
AppDelegateはApp(application)がすべきことを代わりに具現するという意味です。
アプリがすることは、バックグラウンド進入、フォーグラウンド進入、外部からの要請などがあります。
- アプリのデータ構造の初期化
- アプリのsceneを環境設定(Configuration)すること
- アプリ外で発生したお知らせ(バッテリー不足、ダウンロード完了など)に対応
- 特定のscene、view、view controllersに限らず、アプリ自体のターゲットイベントに対応
- Appleプッシュ通知サービスのように実行時に要求されるすべてのサービス登録
AppDelegateクラスの上には@mainアノテーションがある。 このアノテーションからUIaplicationがAppDelegateが本人の役割を委任されたクラスであることがわります。
iOS13以前の12まではAppDelegateで作業を終えたが、iOS13からSession LifecycleをAppDelegateとSceneDelegateが分けて担当しています。
iOS12までは一つのアプリに一つのwindowだったが、iOS13からはwindowの概念がsceneに代替され、一つのアプリで複数のsceneを持つことができるようになった。
AppDelegateの役割の一つだったUI状態がわかるUILifeCycleをSceneDelegateが担当します。
そしてAppDelegateにSession Lifecycleの役割が追加されました。 Scene Sessionが生成されたり削除されたりする際にApp Delegateに知らせるメソッドが2つ追加されました。 Scene Sessionはアプリで生成したすべてのSceneの情報を管理します。
AppDelegateメソッド
3つのメソッドが存在します。
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
return true
}
application:did Finish Launching With Optionsは、アプリがユーザーに表示される前に初期化を進める段階です。
// MARK: UISceneSession Lifecycle
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)
}
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.
}
AppDelegateでSceneSessionを通じてSceneに関する情報をアップデートしてもらいます。
Scene Sessionが新しくできたとき、Scene Sessionが削除されたときに呼び出されるメソッドです。 scene をプログラミング的に生成、管理するメソッドです。
Scene, SceneSessionとは
SceneにはUIの一つのインスタンスを表すWindowsとview controllersが入っています。 また、各sceneに該当するUIWindowSceneDelegateオブジェクトを持っており、このオブジェクトはUIKitとアプリ間の相互作用を調整するのに使用します。 Sceneは同じメモリとアプリプロセス空間を共有しながら同時に実行されます。 結果的に、一つのアプリは複数のsceneとscene delegateオブジェクトを同時に活性化することができます。
UISceneSessionオブジェクトは、scene固有のランタイムインスタンスを管理します。 ユーザーがアプリに新しいsceneを追加したりプログラミング的にsceneを要請すると、システムはそのsceneを追跡するセッションオブジェクトを生成します。 そのセッションには固有の識別子とsceneの構成詳細(configuration details)が含まれています。 UIKitはセッション情報をsceneの生涯の間維持し、ユーザーがそのsceneをクロージングすると、そのセッションを破壊します。 セッションオブジェクトは直接生成するのではなく、UIKitがアプリのユーザーインターフェースに対応して生成します。
SceneDelegate
SceneDelegateは画面に何を表示するかを管理する役割を果たします。
-
scene(_: willConnectTo: options: )
UISceneSessionlifecycleで最初に呼ばれるメソッドで新しいUIWindowを生成し、windowのrootViewControllerを設定します。 この時のwindowはユーザーが見るのではなく、アプリが作動するviewportです。 最初のviewを作るのに使われることもありますが、過去にdisconnectedされたUIを戻す時も使うこともあります。 -
sceneWillEnterForeground(_ :)
sceneがセットされ、画面に表示されて使用する準備が完了した状態です。 inactive -> active切替時に呼び出されます。 -
sceneWillResignActive(_:)
activeな状態からinactive状態に陥るときに呼ばれます。 使用中に電話がかかってくるような一時的な状況のために発生する可能性があります。 -
sceneDidEnterBackground(_:)
sceneがフォアグラウンドからバックグラウンドに切り替わるときに呼ばれるようになります。 次に再びフォーグラウンドに戻る時に復元できるように状態情報を保存したり、データを保存、共有リソースを返すなどの仕事をするようにすればいいです。 -
sceneDidDisconnect(_:)
sceneがバックグラウンドに入ったとき、システムがリソースを確保するためにdisconnect(sceneがこのメソッドに伝わると、セッションから切断される。)することもできます。 このメソッドで最も重要な作業は、不要なリソースを返すことです。 ディスクやネットワークを通じて簡単に読み取れたり生成しやすいデータは返し、ユーザーのinputのように再生性が難しいデータは持っているようにする作業をしてくれます。
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
var navigationController: UINavigationController?
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).
let rootVC = LaunchScreenVC()
rootVC.view.backgroundColor = .white
self.navigationController = UINavigationController(rootViewController: rootVC)
self.window?.rootViewController = self.navigationController
}
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 necessarily 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.
}
}
Discussion