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の処理、プッシュ通知の登録などを行います。
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
print("アプリが起動しました。")
configureThirdPartyLibraries() // サードパーティライブラリの設定
setupDefaultSettings() // デフォルト設定
return true
}
didDiscardSceneSessions
- 不要なSceneが削除されるときに呼び出されます。
- 削除されたSceneに関連するリソースをクリーンアップします。
func application(
_ application: UIApplication,
didDiscardSceneSessions sceneSessions: Set<UISceneSession>
) {
print("Sceneが削除されました。")
for session in sceneSessions {
cleanUpResources(for: session)
}
}
SceneDelegate
sceneDidBecomeActive
- Inactive状態からActive状態に切り替わるタイミングで呼び出されます。
- ユーザーとの対話が可能になり、UIの更新やユーザーのアクティビティ追跡を再開します。
func sceneDidBecomeActive(_ scene: UIScene) {
print("Sceneがアクティブになりました。")
startUpdatingUserInterface() // UI更新の再開
}
sceneWillResignActive
- Active状態からInactive状態に切り替わる直前に呼び出されます。
- UIの更新を停止したり、データを保存する処理に使用されます。
func sceneWillResignActive(_ scene: UIScene) {
print("Sceneが非アクティブになります。")
stopUpdatingUserInterface() // UI更新の停止
}
sceneDidEnterBackground
- Sceneがバックグラウンドに移行するときに呼び出されます。
- アプリの状態を保存したり、バックグラウンドタスクを実行します。
func sceneDidEnterBackground(_ scene: UIScene) {
print("Sceneがバックグラウンドに移行しました。")
saveApplicationState() // アプリ状態の保存
startBackgroundTask() // バックグラウンドタスクの開始
}
sceneWillEnterForeground
- バックグラウンドからフォアグラウンドに復帰する直前に呼び出されます。
- UIの更新やデータのリフレッシュを行います。
func sceneWillEnterForeground(_ scene: UIScene) {
print("Sceneがフォアグラウンドに復帰します。")
refreshUserInterface() // UIのリフレッシュ
}
sceneDidDisconnect
- Sceneが完全に削除される際に呼び出されます。
- 関連リソースの解放やメモリのクリーンアップを行います。
func sceneDidDisconnect(_ scene: UIScene) {
print("Sceneが切断されました。")
cleanUpSceneResources() // リソースの解放
}
5. 実務での活用事例
- データの保存と復元
バックグラウンドに移行する際にデータを保存し、フォアグラウンドに復帰する際に復元します。
func sceneDidEnterBackground(_ scene: UIScene) {
saveUserData()
}
func sceneWillEnterForeground(_ scene: UIScene) {
loadUserData()
}
- ユーザーの活動追跡
アクティブ状態で追跡を開始し、非アクティブ状態で停止します。
func sceneDidBecomeActive(_ scene: UIScene) {
startAnalyticsTracking()
}
func sceneWillResignActive(_ scene: UIScene) {
stopAnalyticsTracking()
}
- バックグラウンドタスクの処理
beginBackgroundTaskを使用して、制限時間内でバックグラウンドタスクを実行します。
func sceneDidEnterBackground(_ scene: UIScene) {
let taskID = UIApplication.shared.beginBackgroundTask {
print("バックグラウンドタスクの時間切れです。")
}
performBackgroundTask()
UIApplication.shared.endBackgroundTask(taskID)
}
6. 結論
-
AppDelegateとSceneDelegateの役割分担
アプリの初期化や全体的なイベントはAppDelegateで処理し、画面ごとの操作はSceneDelegateで管理します。 -
データロスを防ぐ
バックグラウンド移行時にデータを保存し、復帰時に適切に復元します。 -
マルチウィンドウサポート
マルチウィンドウ環境では、各Sceneのライフサイクルを適切に管理します。 -
バックグラウンド作業の最適化
制限時間を考慮しながら効率的に設計します。
参考文献
- Apple公式ドキュメント: Managing Your App's Life Cycle
- Apple公式ドキュメント: UISceneDelegate