LoginSignup
19
20

More than 5 years have passed since last update.

NotificationCenterを使用して、アプリの状態を認識する

Last updated at Posted at 2019-02-15

エンジニアのことエンディニアっていうやつだいたい癖強い。
どうもこんにちはTOSHです。

中高生にプログラミングを教えていると、文化祭用にアプリを開いた状態で時刻を取得するアプリを作りたいと言われました。
基本的には、そこら辺の動作はAppDelegateのなかで管理しやすいのかなと思ったけど、通常のViewControllerの中でも管理できるのかなということでやっていきます。

今回はNotificationCenterを使用して、アプリのフォアグラウンド状態、バックグラウンド状態を認識する方法を紹介していきたいと思います。
何かおかしい事等あったら、ご指摘お願いします。

アプリの状態について

基本的に大きく分けて、状態としては2つ。
・フォアグラウンド:画面上で動いている状態。
・バックグラウンド:画面上にはそのアプリは動いていないが、裏ではコードが動いている状態。

さらに、フォアグラウンドには、inactiveとactiveな状態があるようですね。
それぞれ、
・inactive:スクリーン上で動いているが、イベントを受け取っていない状態
・active:スクリーン上で動いているし、イベントを受け取っている状態

これらを図にすると以下のような感じ
00b28327-17dc-4f0c-866f-29f854edfce3.png
*Appleの公式ページより参照

少し前に、使われた画像も参考までに
high_level_flow_2x.png
*こちらも同様にAppleのページより参照

という事で、今回はアプリを開いた時の状態を認識したいので、backgroundからACtiveになる状態を認識する。

実装方法

ネットでググってみるとNSNotificationCenterを使用しているコードは多数見つかるものの、なかなか、NotificationCenterを使用しているコードは見つからなかったので、まとめておきます。
少し文法が変わっていたので、参考になればと思います。

//NotificationCenterを定義
let notificationCenter = NotificationCenter.default

//observerを追加        
notificationCenter.addObserver(
    self,
    selector: #selector(呼び出したいメソッド名),
    name: UIApplication.ここに変化を感知させたい状態を書く,
    object: nil
)

よく使用しそうなNotificationのみを抜粋して一覧にしておきます。

UIApplication. 説明
didBecomeActiveNotification アプリがActiveになるときに投げられる
didChangeStatusBarFrameNotification ステータスバーのフレームが変更されるときに投げられる
didEnterBackgroundNotification アプリがバックグラウンドに入るときに投げられる
didFinishLaunchingNotification launch(起動)が終わった直後に投げられる
willTerminateNotification アプリがterminate(終了)する直前に投げられる
willEnterForegroundNotification バックグラウンドから離れ、アプリがアクティブになるちょっと前に投げられる
willResignActiveNotification Activeではなくなるときに投げられる

詳しくは、UIApplicationを参照してください。

意外と、読んで見ても違いがわかりずらいものもあったりするので、実際に動かしてみるといいと思います。
今回は、一番上のdidBecomeActiveNotificationを使用してみます。

全体のコードは以下の感じ

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var currentTimeLabel: UILabel!

    var currentTime: Date!
    let formatter = DateFormatter()

    override func viewDidLoad() {
        super.viewDidLoad()

        //現在時刻を取得
        currentTime = Date()

        //NotificationCenterを定義
        let notificationCenter = NotificationCenter.default

        //Observerを追加
        notificationCenter.addObserver(
            self,
            selector: #selector(self.currentTimeUpdate),
            name: UIApplication.didBecomeActiveNotification,
            object: nil
        )

        currentTimeLabel.text = dateFormatting()
    }

    //observerが発火したタイミングで呼ばれるメソッド
    @objc func currentTimeUpdate() {
        currentTime = Date()
        currentTimeLabel.text = dateFormatting()
    }

    //Date型をString型に変更するための処理
    func dateFormatting() -> String {
        //今回は、時、分、秒で変換している
        formatter.setLocalizedDateFormatFromTemplate("jms")

        return formatter.string(from: currentTime)
    }
}

実際に動いているのがこちら、
gif
ちゃんと、アプリを開いたら時刻が変化していますね。

GitHub

今回のサンプルコードをGitHubの方にあげておきました、参考までにどうぞ!
GitHub

参考にしたページ

Managing Your App's Life Cycle
アプリの状態が変わったタイミングで処理を行わせる実装
アプリの状態とマルチタスキング
The App Life Cycle

19
20
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
19
20