AppDelegateを調べてみた

AppDelegateについて使うメソッドしか理解できておらず、私の中でブラックボックスになっていたので、公式ドキュメントを読んで理解したことをまとめます。

全てを網羅するのは大変なのでデフォルトで記述されているメソッドを対象とします。

application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool

アプリケーションの起動時の初期Viewを設定したりする場所。NavifationBarをつける時とや、rootViewControllerの変更を行う際に使う場所。個人的に一番頻繁に使うところではないかと思っている。

NavigationBarをつける例

let nv = UINavigationController(rootViewController: ViewController())
window?.rootViewController = nv

launchOptionにはアプリが起動された理由が辞書型で入っている。ユーザが直接アプリを開いた場合値が入っていない可能性がある。

通常戻り値はtrueで返しているがfalseで返すべき場合はURLリソースの処理ができない場合やユーザのアクセシビリティを続行できない場合にfalseを返すのが良いらしい

applicationWillResignActive(_ application: UIApplication)

アプリがアクティブ状態から非アクティブ状態に移行する際にこのメソッドが呼ばれます。つまりアプリがバックグラウンドになったことを検知して行いたい処理を記述します。
ゲームを一時停止する際にもこのメソッドを利用するのが良いようです。

バックグラウンドで処理をしたいとき

アプリがバックグラウンドになってしまった場合処理が5秒程度で完全にストップしてしまいますが、データベースへのデータのアップロードやbluetooth通信を続けたい場合以下のようにendBackgroundTaskを登録することで、一定時間処理を行うことができます

var backgroundTaskID: UIBackgroundTaskIdentifier = UIBackgroundTaskIdentifier(rawValue: 0)
    func applicationWillResignActive(_ application: UIApplication) {
        //バックグラウンドで行いたい処理があるとき
        backgroundTaskID = application.beginBackgroundTask {
            [weak self] in
            application.endBackgroundTask((self?.backgroundTaskID)!)
            self?.backgroundTaskID = UIBackgroundTaskIdentifier.invalid
        }
    }

applicationDidEnterBackground(_ application: UIApplication)

共有リソースの会報や、タイマーの無効化など終了した際にアプリを綺麗な状態にするためのメソッドです。

applicationWillResignActive(_ application: UIApplication)で紹介したアプリをバックグラウンドでも動かすタスクを作成した場合applicationWillTerminate(_ application: UIApplication)の代わりにこのメソッドが呼ばれます。

applicationWillEnterForeground(_ application: UIApplication)

このメソッドはアプリがフォアグラウンドの状態に復帰した時に呼ばれます。
アプリがバックグラウンドになった時に一時退避していた値などを元の状態に戻すために使います。

このメソッドの次は必ずapplicationDidBecomeActive(_:) が呼ばれます。

applicationDidBecomeActive(_ application: UIApplication)

アプリがフォアフランドに復帰したときapplicationWillEnterForeground(_ application: UIApplication)の次に呼ばれるメソッドです。ユーザからの起動、システムからの起動の両方ともこのメソッドを通ります。


タイマーを再起動したりユーザインターフェースを更新したりする処理はここで書くのが良いようです。

didBecomeActiveNotificationを受け取る例

applicationWillEnterForeground(_ application: UIApplication)が呼び出される直前に通知を送信しているためNotificationCenterで通知を受け取ることができます。

override func viewDidLoad() {
    super.viewDidLoad()

    let notificationCenter = NotificationCenter.default
    notificationCenter.addObserver(
        self,
        selector: #selector(self.myEvent),
        name: UIApplication.didBecomeActiveNotification,
        object: nil
    )
}
@objc func myEvent() {
   //フォアグラウンド復帰時に行いたい処理 		
}

applicationWillTerminate(_ application: UIApplication)

アプリの実行中のみ呼び出されバックグラウンドにいる場合このメソッドは呼ばれません。
このメソッドは、アプリケーションが強制終了されてメモリが完全に削除される直前に呼ばれます。ユーザデータの保存や共有リソース、タイマーの無効化などを行います。タスクの終了には役5秒かかりますが、それを超えてしまうとシステムが完全に終了してしまします。

willTerminateNotification

willTerminateNotificationでNotificationCenterに通知を飛ばせるようです。

NotificationCenter.default.addObserver(forName: NSNotification.Name.UIApplicationWillResignActive,
                                                                       object: nil,
                                                                       queue: nil) { _ in
//終了時に行いたい処理
}

参考文献

UIApplicationDelegate