iOSアプリのライフサイクル (Life Cycle)

## 1. アプリのライフサイクルとは？
アプリを使用中に電話がかかってくると、アプリは自動的に電話画面に切り替わり、非アクティブ状態になります。

このように、アプリは使用中にユーザーの行動やイベントによって様々な状態に切り替わります。この仕組みを「ライフサイクル」と呼びます。

iOSはアプリの状態を管理し、その状態に応じたイベントを `AppDelegate` や `SceneDelegate` を通じて開発者に提供します。

## 2. アプリの主要な状態
iOSアプリはシステムの状態変化に応じて、次のような主要な状態を持ちます。
```
Not Running → Inactive → Active
    ↑          ↓          ↓
    Suspended ← Background
```

- **Not Running**
アプリが実行されていない状態。メモリにロードされていない場合を含む。
- **Inactive**
アプリが実行中だが、イベントを受け取らない状態。
例: 電話の着信や通知の表示など。
- **Active**
アプリが実行中で、ユーザー操作を受け付ける状態。
- **Background**
アプリがバックグラウンドで実行中の状態。制限付きのタスクが可能。
- **Suspended**
アプリがメモリに保持されるが、コードの実行が停止している状態。システムリソースが不足すると終了する場合がある。

これらの状態遷移は、ユーザーの行動（ホームボタンの押下、アプリの終了など）やシステムイベント（メモリ不足など）によって発生します。

## 3. AppDelegateとSceneDelegateの役割
#### AppDelegate
アプリ全体のライフサイクルを管理します。
iOS 13以前は、すべてのライフサイクル管理をAppDelegateが担当していましたが、iOS 13以降はSceneDelegateと役割が分割されました。
主にアプリの初期設定や全体的なイベントを処理します。

#### SceneDelegate
iOS 13以降に導入され、アプリの各**Scene 画面**のライフサイクルを管理します。
マルチウィンドウ環境のサポートを目的として設計されました。

## 4. 主なライフサイクルイベントと活用方法
#### AppDelegate
`didFinishLaunchingWithOptions`
- アプリが起動直後に呼び出されます。
- アプリの初期化作業や外部URLの処理、プッシュ通知の登録などを行います。

```swift
    func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
        print("アプリが起動しました。")
        configureThirdPartyLibraries() // サードパーティライブラリの設定
        setupDefaultSettings()         // デフォルト設定
        return true
    }
```

`didDiscardSceneSessions`
- 不要なSceneが削除されるときに呼び出されます。
- 削除されたSceneに関連するリソースをクリーンアップします。
```swift
    func application(
        _ application: UIApplication,
        didDiscardSceneSessions sceneSessions: Set<UISceneSession>
    ) {
        print("Sceneが削除されました。")
        for session in sceneSessions {
            cleanUpResources(for: session)
        }
    }
```
#### SceneDelegate
`sceneDidBecomeActive`
- Inactive状態からActive状態に切り替わるタイミングで呼び出されます。
- ユーザーとの対話が可能になり、UIの更新やユーザーのアクティビティ追跡を再開します。
```swift
    func sceneDidBecomeActive(_ scene: UIScene) {
        print("Sceneがアクティブになりました。")
        startUpdatingUserInterface() // UI更新の再開
    }
```
`sceneWillResignActive`
- Active状態からInactive状態に切り替わる直前に呼び出されます。
- UIの更新を停止したり、データを保存する処理に使用されます。
```swift
    func sceneWillResignActive(_ scene: UIScene) {
        print("Sceneが非アクティブになります。")
        stopUpdatingUserInterface() // UI更新の停止
    }
```
`sceneDidEnterBackground`
- Sceneがバックグラウンドに移行するときに呼び出されます。
- アプリの状態を保存したり、バックグラウンドタスクを実行します。
```swift
    func sceneDidEnterBackground(_ scene: UIScene) {
        print("Sceneがバックグラウンドに移行しました。")
        saveApplicationState() // アプリ状態の保存
        startBackgroundTask()  // バックグラウンドタスクの開始
    }
```
`sceneWillEnterForeground`
- バックグラウンドからフォアグラウンドに復帰する直前に呼び出されます。
- UIの更新やデータのリフレッシュを行います。
```swift
    func sceneWillEnterForeground(_ scene: UIScene) {
        print("Sceneがフォアグラウンドに復帰します。")
        refreshUserInterface() // UIのリフレッシュ
    }
```
`sceneDidDisconnect`
- Sceneが完全に削除される際に呼び出されます。
- 関連リソースの解放やメモリのクリーンアップを行います。
```swift
    func sceneDidDisconnect(_ scene: UIScene) {
        print("Sceneが切断されました。")
        cleanUpSceneResources() // リソースの解放
    }
```

## 5. 実務での活用事例
1) データの保存と復元
バックグラウンドに移行する際にデータを保存し、フォアグラウンドに復帰する際に復元します。
```swift
    func sceneDidEnterBackground(_ scene: UIScene) {
        saveUserData()
    }
    
    func sceneWillEnterForeground(_ scene: UIScene) {
        loadUserData()
    }
```

2) ユーザーの活動追跡
アクティブ状態で追跡を開始し、非アクティブ状態で停止します。
```swift
    func sceneDidBecomeActive(_ scene: UIScene) {
        startAnalyticsTracking()
    }
    
    func sceneWillResignActive(_ scene: UIScene) {
        stopAnalyticsTracking()
    }
```

3) バックグラウンドタスクの処理
beginBackgroundTaskを使用して、制限時間内でバックグラウンドタスクを実行します。
```swift
    func sceneDidEnterBackground(_ scene: UIScene) {
        let taskID = UIApplication.shared.beginBackgroundTask {
            print("バックグラウンドタスクの時間切れです。")
        }
        performBackgroundTask()
        UIApplication.shared.endBackgroundTask(taskID)
    }
```

## 6. 結論
1. **AppDelegateとSceneDelegateの役割分担**
アプリの初期化や全体的なイベントはAppDelegateで処理し、画面ごとの操作はSceneDelegateで管理します。
2. **データロスを防ぐ**
バックグラウンド移行時にデータを保存し、復帰時に適切に復元します。
3. **マルチウィンドウサポート**
マルチウィンドウ環境では、各Sceneのライフサイクルを適切に管理します。
4. **バックグラウンド作業の最適化**
制限時間を考慮しながら効率的に設計します。

--- 

参考文献
- Apple公式ドキュメント: Managing Your App's Life Cycle

https://developer.apple.com/documentation/uikit/app_and_environment/managing_your_app_s_life_cycle

- Apple公式ドキュメント: UISceneDelegate

https://developer.apple.com/documentation/uikit/uiscenedelegate