見出し画像

Lesson 4.2 App Anatomy and Life Cycle

前のユニットの最後に、View Controllerのライフサイクルのさまざまな段階について学びました。アプリのライフサイクルはほぼ同じように機能します。アプリが開き、実行され、バックグラウンドに入り、閉じます。

このレッスンでは、さまざまなライフサイクル状態と、アプリが各状態を移動するときにロジックを実行するためのデリゲートフックについて詳しく学びます。

あなたが学ぶこと

アプリのライフサイクルのさまざまな段階でコードを実行する方法

Vocabulary
active
app delegate
app state
foreground

p.548 
ほとんどのiOSアプリは、ユーザーが開いたときに実行され、ユーザーがホームボタンを押したり、アプリスイッチャーを使用したり、別のアプリに切り替えたりすると実行を停止します。

プログラマーとして、アプリのライフサイクルにおけるこれらのイベントのいずれかで、デリゲートメソッド、またはコードを実行できるフックがあります。たとえば、アプリが起動すると、新しいデータを取得するためのネットワークコールをトリガーすることもできます。アプリが閉じたら、ユーザーの進捗状況を保存したい場合があります。また、アプリデリゲートは、アプリがiOSや他のiOSアプリで正しく動作することを確認します。

このレッスンでは、新しいプロジェクトごとにXcodeが作成するAppDelegate.swiftファイルを調べます。これは、前景から背景に移動するときなど、アプリがライフサイクルを通じて移行する際に呼び出される最も一般的なデリゲートメソッドを学ぶのに役立ちます。

コードを掘り下げる前に、アプリのライフサイクルのさまざまな段階を理解する必要があります。

p.549 
デリゲートを分解する

シングルビューアプリケーションテンプレートを使用して新しいプロジェクトを作成し、「AppLifeCycle」という名前を付けます。

プロジェクトナビゲータで、AppDelegateクラスを定義するAppDelegate.swiftを開きます。AppDelegateクラスは、アプリのライフサイクル内のさまざまなイベントへのフックとして機能するメソッドを定義するUIApplicationDelegateプロトコルに準拠しています。

アプリデリゲートに含まれる方法を見て、コメントを読んで、その作業について学んでください。

p.550 
打ち上げは終わりましたか?

アプリの起動が終了すると、最初の関数が呼び出され、アプリで独自のコードを実行する最初の機会が与えられます。

アクティブに辞任します

次の関数は、アプリがフォアグラウンドまたはアクティブな状態を離れようとしているときに呼び出されます。このイベントは、ユーザーがアプリを終了したときに発生する可能性がありますが、アプリが電話やシステムアラートによって一時的に中断されたときにも呼び出されます。

これは、要求の厳しいプロセスをスピンダウンし、ユーザーの作業や進捗状況を節約する適切な時期です。

p.551 
背景を入力しましたか?

次のメソッドは、アプリが実際にバックグラウンド状態に入ると、applicationWillResignActive(_:)メソッドの直後に呼び出されます。

ユーザーがアプリを終了した結果としてメソッドが呼び出された場合、この関数はアプリがメモリから完全に閉じられる前に、作業を実行するのに約5秒かかります。

前景に入ります

次の関数は、applicationDidBecomeActive関数の直前に、バックグラウンドからアクティブ状態への移行の一部として呼び出されます。このメソッドを使用すると、バックグラウンドに入ったときにアプリに加えられた多くの変更を元に戻すことができます。

p.552 
アクティブになりましたか?

このメソッドは、非アクティブ状態からアクティブ状態に移行したことをアプリに知らせるために呼び出されます。これは、アプリがユーザーまたはシステムによって起動されたために発生する可能性のあるトランジションです。ユーザーがアプリを一時的に非アクティブな状態に送信した着信電話やシステムアラートなどの割り込みを無視することを選択した場合、アプリはアクティブな状態に戻ることもできます。

終了します

最後のメソッドは、それが終了し、メモリからクリアされようとしていることをアプリに伝えます。applicationDidEnterBackgroundと同様の目的を果たしますが、さまざまな種類のアプリに使用します。

どの方法が正しいですか?GPSの方向性を提供するアプリ、音楽を再生するアプリ、音声通話を処理するアプリなど、バックグラウンドでコードを実行することが許可されているアプリについては、applicationDidEnterBackground関数を呼び出す必要があります。通常はバックグラウンドで実行されないアプリでは、applicationWillTerminate関数を使用します。

p.553 
試してみてください


メソッドをトリガーするために何が起こったのかを説明する各デリゲートメソッドにprint文を追加します。たとえば、applicationDidFinishLaunching(_:)メソッドのprint("Did finish launching.")、applicationWillResignActive(_:)のprint("Will resign active.")。

シミュレーターでアプリを実行します。アプリを開くと、2つのメッセージがコンソールに印刷されます。

Shift + Command + Hキーを押して、ホームボタンを押してアプリを閉じるシミュレーションを行います。さらに2つのメッセージがコンソールに出力されます。

Shift + Command + Hを2回押してアプリスイッチャーを開き、アプリを再度開きます。コンソールにさらに2つのメッセージが出力されます。

アプリスイッチャーをもう一度開き、アプリに戻ります。

p.554 
さまざまなデリゲートメソッドと、アプリを構築する際にそれらをどのように使用するかをメモしてください。この演習からわかるように、ビルドするすべてのアプリでそれらすべてを使用する必要はないかもしれませんが、各アプリのトランジションでコードを実行するための便利なフックを提供します。

どの方法を使うべきですか?

アプリのさまざまなトランジションに応答するための多くのオプションについて学びました。今のところ、アプリの起動、再開、または終了時に実行される3つの方法に焦点を当てます。

アプリケーションDidFinishLaunchingWithOptions

アプリケーションWillResignActive

アプリケーションDidBecomeActive

より経験豊富になり、より複雑なアプリを構築するにつれて、他の3つのデリゲートメソッドを利用したい状況に遭遇します。 

p.555 
目標

このラボの目的は、アプリのライフサイクルを視覚的に表現するアプリを作成することです。異なるデリゲートメソッドが呼び出されると、アプリはビューのラベルを更新します。

シングルビューアプリケーションテンプレートを使用して「AppEventCount」という新しいプロジェクトを作成し、デバイスファミリをユニバーサルに設定します。

ステップ1:ビューとビューコントローラを設定する

すべての単一のビューアプリと同様に、アプリは1つのビューコントローラーから始まります。6つのラベルをドラッグし、6つのAppDelegateライフサイクルメソッドのそれぞれに1つずつドラッグします。必要に応じて制約を設定します。ヒント:スタックビューの使用を検討してください。

ラベルを使用して、特定のアプリイベントが発生した回数を表示します。「didFinishLaunchingLabel」や「didBecomeActiveLabel」などの説明的な名前を使用して、各ラベルのアウトレットを作成します。

また、各ラベルについて、デリゲートメソッドが何回発生したかのカウントを格納する変数を作成します。次の例のように、各変数の初期値を0に設定します。

Var launchCount = 0

updateView() メソッドを作成し、viewDidLoad() で呼び出します。次の例のように、このメソッドの各ラベルを設定して、対応するカウントを表示します。

didFinishLaunchingLabel.text = "アプリは\(launchCount)時間を起動しました"

ステップ2:AppDelegateにViewControllerへのアクセスを許可する

AppDelegateクラスでは、行var window:UIWindow?のすぐ下で、ViewController?型の「viewController」という変数プロパティを作成します。必ずオプションにしてください。

applicationDidFinishLaunching(_:) メソッドで、プロパティ viewController を rootViewController に等しく設定します。これにより、AppDelegateはViewControllerのインスタンスにアクセスでき、次の例のように、アプリのライフサイクルメソッドが呼び出されるたびにViewControllerの対応するカウントプロパティをインクリメントするコードを書くことができます。

p.556 
ステップ3:カウントプロパティをインクリメントする

applicationDidFinishLaunchingで、アプリの起動に対応するViewControllerプロパティの数を増やします。

viewController?.launchCount += 1

applicationWillResignActive、applicationDidEnterBackground、applicationWillEnterForeground、applicationDidBecomeActive、applicationWillTerminateの他の5つの方法で上記の手順を繰り返します。

ステップ4:ビューを定期的に更新する

各アプリイベントの新しいカウントを表示するには、ビューを定期的に更新する必要があります。ViewControllerのviewDidLoad()メソッドでupdateView()を呼び出すと思うかもしれませんが、問題があります。viewDidLoad()はすべてのアプリイベントで呼び出されません。ビューを更新するのに最適な場所があります。アプリイベントメソッドの1つであるapplicationDidBecomeActiveは、他の各ライフサイクルメソッドが呼び出された後、ユーザーがアプリを再度操作できる直前に呼び出されます。applicationDidBecomeActiveイベントは、ビューコントローラのupdateView()を呼び出すのに最適な場所であり、ラベルに適切なカウントが表示されるようにします。

ステップ5:テスト

シミュレーターでアプリを実行します。

didFinishLaunchingLabelとdBecomeActiveLabelの両方のラベルは、そのカウントに1を示す必要があります。

Command + Shift + Hキーを押して、シミュレータのホーム画面に移動します。

アプリをタップして、他のどのラベルが変更されたかを確認してください。

p.557 
Command + Shift + Hをすばやく2回押し(ホームボタンを2回押すシミュレーション)、アプリスイッチャーを起動します。しかし、アプリを変更する代わりに、同じアプリに戻ります。どのラベルが変更されましたか?

ユーザーがアプリを終了すると、applicationWillTerminate(_:)メソッドが呼び出されます。しかし、現在、アプリのデータが終了の間に失われるため、アプリが終了した回数を表示する方法はありません。その結果、あなたの didTerminateLabelは0より大きいカウントを表示することはありません。同様に、あなたのdinishLaunchingLabelは1より大きいカウントを表示することはありません。

よくやった!アプリのライフサイクルを視覚化するのに役立つアプリを作成しました。必ずプロジェクトフォルダに保存してください。

この記事が気に入ったらサポートをしてみませんか?