LoginSignup
0
2

More than 3 years have passed since last update.

iOSのdidBecomeActive/willResignActiveを視覚的に把握する

Last updated at Posted at 2020-09-12

モチベーション

ライフサイクルメソッドの説明は、解説付きでケースを列挙されることが多いですが、いまいちイメージがしにくいと感じることが多く感じます。特に、ActiveとInactiveのタイミングは分かりにくいことが多いのではないでしょうか。

この記事では、Sceneベースの各種ライフサイクルメソッドにprintを貼って、active/inactiveとはどのようなステートなのかを視覚的に把握します。(※タイミングの列挙はしません。1つ2つ取り上げるだけです)

解説

1. アプリの起動

スクリーンショット 2020-09-12 15.00.45.png

ライフサイクル

シーンベースのライフサイクルでも、共通系は呼ばれます。なのでdidFinishLauchingがまず始めに呼ばれます。
次に、SceneDelegatewillConnectが呼ばれます。このメソッドは、システム・ユーザー起点にかかわらず、新しいシーンがアプリケーションに接続される直前に呼ばれます。そしてその後は順当にwillEnterForeground, didBecomeActiveと呼ばれていきます。

didFinishLaunching
willConnect
willEnterForeground
didBecomeActive

2. SplitViewの割合変化

もっとも分かりやすい状態遷移です。視覚的な状態と実際の状態が一致しており、直感的に理解できます。

中間状態

スクリーンショット 2020-09-12 15.41.42.png

ライフサイクル

中間状態では、システムによるSplitViewの操作中で、アプリケーション自体の操作はできないため、画面は前面に出ていますがInactiveな状態です。

didFinishLaunching
willConnect
willEnterForeground
didBecomeActive
willResignActive

完了

スクリーンショット 2020-09-12 15.41.52.png

ライフサイクル

割合がユーザーによって決められ、操作が終了するとdidBecomeActiveが呼ばれていることが分かります。

注目すべきは、どちらの状態でもforegroundであることは変わらず、active/inactiveだけの変化であるということです。

didFinishLaunching
willConnect
willEnterForeground
didBecomeActive
willResignActive
didBecomeActive

3. SplitViewから閉じる

スクリーンショット 2020-09-12 15.31.50.png

ライフサイクルメソッド

先程の中間状態からの復帰ではdidBecomeActiveになりましたが、こちらはそのまま閉じてしまった(右側の比率を100%にした)ので、didEnterBackgroundが呼ばれました。

didFinishLaunching
willConnect
willEnterForeground
didBecomeActive
willResignActive
didBecomeActive
willResignActive
didEnterBackground

まとめ

「ForegroundなのにInactiveな状態ってどのようなものなのだろう?」という疑問に対して、これまで「システム的にはそういう状態が存在する」と受け入れて理解していた人も、上記のSplitViewの例を見れば「前面に出ているのに、アプリケーションにアクセスできない瞬間が存在する」というのを視覚的に把握できたかと思います。

他には、アプリ一覧を開いた時にInactiveになったりしますが、詳細は別の方の記事をご参照ください。

実装

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

    // 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.
        print("configurationForConnecting")
        return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
    }

SceneDelegate.swift
import UIKit

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 }
        print("willConnect")

    }

    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).
        print("didDisconnect")
    }

    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.
        print("didBecomeActive")

    }

    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).
        print("wiiResignActive")

    }

    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.
        print("willEnterForeground")

    }

    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.

        // Save changes in the application's managed object context when the application transitions to the background.
        (UIApplication.shared.delegate as? AppDelegate)?.saveContext()
        print("didEnterBackground")

    }


}



0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2