いったんプログラムを終了してもデータが保存されていることを確かめる
上の例を見ても「1つのプログラムの中でデータを書いて、そのまま読み出したのでは、本当に保存されているのか定かではない」と疑われるかもしれません。
そこで、プログラムをいったん終了しても、ユーザーデフォルトに書き込んだデータが保存されていることを確かめるプログラムを書いてみましょう。このプログラムでは、指定したキーに対して読み出した値がnilの場合だけ、そのキーで「未定義」という文字列を書き込んでいます。その後、そのキーで値を読み出してみたあと、最後に同じキーで「AsciiClub」という文字列を書き込んでいます。
このプログラムを動かすと最初に読み込まれる文字列は「未定義」です。最初は「name」に対する値がnilなので、if文の中で「未定義」が書き込まれるからです。
しかし、このプログラムをいったん終了し、なんならSwift PlaygroundsやiOSまでも終了してから再び動かすと、今度は「AsciiClub」が表示されます。これは前回の動作の最後に書き込んだ値が残っている証拠です。
なお、この例ではUserDefaultsのオブジェクトを作成する際に、suiteNameで指定する名前を「spg76-3」にしていることにお気づきでしょうか。このように、プレイグラウンドごとに別々のデータベース名を指定しないと、Swift Playgroundsのユーザーデフォルトは思ったように機能しないことも判明しました。
前回起動した日時を表示する(だけの)プログラムを作る
ユーザーデフォルトを使って保存/読み込みのできるデータは文字列だけとは限りません。既定の型としては、URL、配列、辞書、文字列の配列、Data、Bool、Int、Float、Doubleなど、豊富にそろっています。それらを活用すれば、いろいろな用途で便利に使えそうなことは想像できるでしょう。
ここでは、ユーザーインターフェースも極力簡単なものにしたミニマムな例として、プログラムを起動した日時を記録しておいて、次に起動した際に、その日時を表示するだけのプログラムを作ってみましょう。これで、プログラムを終了しても、さらにSwift PlaygroundsやiOSを終了しても、データが保存されていることがよりはっきりします。
いつものように、UIKitとPlaygroundSupportをインポートしたあと、ユーザーデフォルトを使って、プログラムの起動日時を記録して、次の起動時に表示するクラス、DefaultViewControllerを定義します。
その中では、ラベル(UILabel)を2つ用意し、1つ目のラベルには固定的に「前回の起動日時」という文字列を、2つ目のラベルにはユーザーデフォルトから取り出した前回の起動日時を表す文字列を表示します。起動日時はviewDidLoadメソッドの最後に近い部分で更新するので、その値は次の起動時にようやく反映されるというわけです。
2つのラベルをビューにレイアウトする部分と、定義したビューコントローラーのオブジェクトを作って、それをプレイグラウンドのライブビューに張り付ける部分のコードは、プログラム起動後の画面で確認してください。
このプログラムを最初に起動した時には、「date」のキーに対するユーザーデフォルトの値はnilの文字列なので、実際の日時部分には何も表示されません。2回目以降は、前回の起動日時を、それからどれだけ経過していようとも正確に表示します。
次回の予定
今回は、予告通り地味な内容になりましたが、iOSアプリの基本的な機能として重要なユーザーデフォルトのSwift Playgroundsならではの使い方を開拓して紹介しました。何らかの実用的なプログラムを書く際には、きっと役に立つこともあるでしょう。次回も、また地味になる可能性が高いのですが、引き続きiOSのデータの扱いについて取り上げる予定です。