ここ何回かは、複数のビューコントローラーのビュー(画面)を切り替えて、あるいは同時に表示するための方法をいろいろと探ってきました。それも前回で一段落したので、今回はまったく毛色の異なるトピックを扱います。前回の最後に書いた予告では「iOSならではのデータの扱い」と書きました。これは、かなりあいまいな表現ですが、今回取り上げるのは、データを保存したり、以前に保存したものをまた読み込んだりするための機能です。
そもそもiOSは、macOSなどに比べると、外部とのデータのやりとりに対する制限が多いのですが、特に出力する方については厳しくなっています。そして、Swift Playgroundsでは、さらにその制限が多くなっています。そんな中で今回は、かなり手軽、かつ便利に使えるユーザーデフォルト(UserDefaults)というクラスを使う方法を紹介します。これは、もともとユーザーが設定したプリファレンスの内容などを保存しておき、次に同じアプリが起動された際には、その設定が適用された状態から始めるためのものです。大量のデータを扱うのには不向きですが、手軽さでは群を抜いています。
ところで、今回から画面ショットがSwift Playgrounds 2.0のものになります。基本的な機能は以前とそれほど変わりませんが、UIの構成があれこれ変わっていたりします。日本語のエラーメッセージも増えましたが、なんだか訳が釈然としません。以前から放置されていたプログラムの繰り返し数を表す「5倍」といった表記は、ようやく「5回」に訂正されました。
教科書どおりでは動かないSwift Playgroundsのユーザーデフォルト
ユーザーデフォルトは、iOSアプリのプログラミングの基本の1つで、あちこちに解説やチュートリアルがあるはずです。ただし、Swiftのバージョンによって正しい表記が変遷してきたので、その部分で混乱する可能性はあります。現在のSwift 4の書き方では、例えば、
let uDef = UserDefaults.standard
のようにして、UserDefaultsクラスの標準オブジェクトを取得し、そのオブジェクトに対して保存したいデータを書き込んだり、逆にそこから取り出したりします。つまり、UserDefaultsのオブジェクトが一種のデータ保存庫のような役割を果たすことになります。
例えば、ここに文字列を書き込むには、
uDef.set("AsciiClub", forKey: "name")
のようにします。この場合「name」というキーを指定して、「AsciiClub」という文字列をデータとして書き込んでいます。
これを読みだすには、データの型ごとに用意されたメソッドを使い、書き込んだ時のキーを指定して、
let title = uDef.string(forKey: "name")
のようにします。
これを実際に動かしてみましょう。
uDefに「name」というキーで書き込んだ文字列データを読み出そうとしているのですが、結果は「nil」、つまり空の文字列になっています。これはプログラムが間違っているわけではありません。実際のiOSアプリでも、Xcode上のプレイグラウンドでも、これで「AsciiClub」という文字列を読みだすことができます。
これはSwift Playgroundsのバグというわけでもないでしょう。プレイグラウンドに書いたプログラムは、それ自体アプリではなく、あくまで「Swift Playgrounds」というアプリ内で動く複数のプログラムの1つに過ぎないのです。そのために「standard」というプロパティで得られるアプリ「標準の」ユーザーデフォルトオブジェクトには書き込みができないと考えられます。
それではSwift Playgroundsでは、そもそもユーザーデフォルトが使えないのでしょうか?そう考えて一度はあきらめかけましたが、もう一度じっくりと考え、標準でだめならカスタムにすれば良いのではないかと思いつきました。UserDefaultsでは、データベースの名前を指定してユーザーデフォルトオブジェクトを作成することもできます。例えば、
let uDef = UserDefaults(suiteName: "spg76")
のようにします。
こうすると、あとは上で示したプログラムのままで、見事ユーザーデフォルトへの書き込み、読み出しができることがわかりました。
この連載の記事
- 第100回 SceneKitの物理現象シミュレーションとアニメーションをARKitに持ち込む
- 第99回 「物理学体」と「物理学場」を設定して物理現象をシミュレーション
- 第98回 SceneKitのノードに動きを加えるプログラム
- 第97回 いろいろな形のノードをシーンの中に配置する
- 第96回 SceneKitの基礎シーンビュー、シーン、ノードを理解する
- 第95回 現実世界の床にボールや自動車のモデルを配置する
- 第94回 ARKitを使って非現実世界との融合に備える
- 第93回 ARKitが使えるiPadを識別するプログラム
- 第92回 Swift Playgrounds 2.1での問題点をまとめて解消する
- 第91回 iPadの内蔵カメラで撮影した写真を認識するプログラム
- この連載の一覧へ