前回から、プログラム内で扱うデータをファイルとして保存したり、また逆に保存したファイルからプログラムの変数にデータを読み込んだりする方法を取り上げています。
iOSの場合、個々のアプリはいわゆる「サンドボックス(sandbox)」に入っていて、ほかのアプリやOS環境とは人為的に遮断された独自の世界で動いています。このサンドボックスは文字どおりの単なる「砂箱」という意味ではなく、臨床心理学のテストや治療で使ったりするもので、日本では「箱庭」と呼ばれています。外部から隔絶されながら、一定の法則の下で動いている擬似世界といった意味です。
アプリをサンドボックスにする理由は、その世界の情報、影響が外部に漏れないようにすることと、逆に外部からその世界に影響が及ばないようにすることにあります。つまり、意図的かそうでないかは別として、あるアプリの動作がOSや他のアプリに悪影響を与えないように防御し、かつ外部からも悪影響、攻撃を受けないように保護します。
Swift Playgroundsというアプリも、もちろんそれ独自のサンドボックス内で動いていますが、その上のプレイグラウンドで動くプログラムは、さらに独自のサンドボックスに入り、二重の壁に囲まれているようなかたちになっています。いろいろと制約が多いのも、そのためと考えられます。
今回は、主にプログラムの起動時に、ファイルからデータを読み込んで必要なデータを初期化するための「プロパティリスト」を扱います。読み込みは簡単ですが、やはり書き込みは制限が多く、今回読み込む場所にあるファイルには書き込めないようになっています。
Xcodeでリソースとして作るプロパティリストは、実はテキストエディットでも作れる
macOSのユーザーなら、何かの機会に拡張子が.plistのファイルを目にしたことがあるかもしれません。一般的にはアプリの初期設定、つまりデフォルトの設定を記録しておくために使われます。それがプロパティリストです。ひと口に初期設定と言っても、アプリによって使い方はさまざまなので、プロパティリストの中身も構成も千差万別です。アプリによっては複数のプロパティリストを使い分けているものもあります。iOSでは目に触れる機会はないはずですが、プロパティリストは、macOSとほとんど同じ目的で同じように使われています。
プロパティリストは、通常はアプリの開発者が、アプリ開発の一環として作ります。そのため、macOSやiOSの開発ツールXcodeを使って、簡単に作れるようになっています。新規のファイルを作成する際に、「Resources」グループにある「Property List」を選べば、専用のエディターが起動します。
プロパティリストのエディターは、慣れないと操作に戸惑うかもしれません。基本的には階層的にデータを構成していくためだけの機能を備えています。
いちばん上の根元の部分には必ず「Root」という項目が置かれています。そしてそのタイプとして「Array」か「Dictionary」を選ぶようになっています。つまり、プロパティリストには、中身として配列を含むものと、辞書を含むものの2種類があることになります。
ただし、それらの配列や辞書の要素のタイプとしては、さらに一段深いレベルの配列や辞書を含むことができるほか、末端(それ以下には子となる要素を含まない)の要素のタイプとしては「Boolean」「Data」「Date」「Number」「String」を選ぶことができます。
これらにより、アプリの初期値として必要なほとんどのタイプのデータを表現することが可能です。とはいえ、かさばりがちな画像、音声、動画といったデータは、別途保存し、プロパティリストには、それらのファイル名やパスを記録しておくのが普通です。
ここではサンプルとして、macOSの主要なアプリケーションのうち、アップルの製品サイトに独立した詳しい説明ページが用意されているもの(全部で8つ)の一覧を表示するためのデータをプロパティリストとして用意することにしました。各項目は辞書として、アプリ名を「name」、そのアイコンのファイル名を「icon」、解説ページのURLを「link」というキーで、いずれもString(文字列)データとして記録します。
プロパティリストは、実はXMLで記述されたテキストファイルとして保存されます。Xcodeがなければ、「テキストエディット」などを使って作成することもできます。
記述はちょっと面倒ですが、同じことの繰り返しがほとんどなので、1つの項目さえ記述できれば、それを増殖させて、値だけを変更していけばいいでしょう。
長年使われてきたプロパティリストを簡単に読み込む方法は今後は使えなくなる
こうして作成したプロパティリストのファイルは、以前に画像ファイルを読み込んだときと同じように、プレイグラウンドに追加する必要があります。それについては、少し後で確認するとして、まずはプロパティリストを読み込むための一般的なプログラムを見てておきましょう。
通常のiOSアプリの場合、プロパティリストは、プログラムと同じプロジェクトに入れておきます。プログラムをコンパイルしたオブジェクトファイルと、画像やプロパティリストなどのリソースは、1つのバンドル(Bundle)の中に記録されます。これはmacOSやiOSで使われるアップル独自のファイル形式のようなもので、複数のファイルを1つにまとめたパッケージと考えることができます。
その中のファイルを読み込むには、メインのバンドルに対してファイル名を指定してパスを取得し、そのパスを指定して直接NSArray(配列の場合)やNSDirctionary(辞書の場合)に読み込むのが一般的でした。NSArrayやNSDictionaryは、Objective-C時代のクラスですが、Swiftでも使えます。
ただし、最近は、なるべくObjective-C時代のクラスは使わず、Swift独自のものを使うようにしようという傾向が強まってきています。そのためだと思いますが、このようにNSArrayやNSDictionayに直接プロパティリストの中身を読み込む方法がごく最近になってデプリケートされてしまいました。現時点ではまだ動きますが、今後はいつ動かなくなっても文句は言えません。Swift Playgroundsでも、まだ使えますが、これから書くプログラムでは、使わないようにするのが賢明です。
それはさておき、この旧式のプログラムを使って、上で作ったプロパティリストを読み込んでみましょう。まずプロパティリストはiCloud Driveに保存しておきます。次に、プレイグラウンドの右上の「+」ボタンをタップして、プロパティリストのファイルをプレイグラウンドに追加する準備をします。
最初は「ファイルなし」の状態になっているので、底辺近くにある「挿入元...」をタップします。するとファイルを選択するダイアログが表示されるので、まず「ブラウズ」で「iCloud Drive」を選んで、ファイルの一覧を表示させます。この例では「MacApps」というのが拡張子(.plist)を除いたプロパティリストのファイル名です。
それを選択するとダイアログが閉じ、「+」で開いたポップアップで「MacApps.plist」が追加されていることが確認できます。
これで準備は完了です。もう一度「+」をタップして、ポップアップを閉じておきます。先ほど入力したプログラムを起動すると、コードの右側部分に実行結果を調べるためのボタンが表示されるはずです。最後の、読み込んだ内容を変数に代入している部分をタップすると、読み込んだ配列の内容がポップアップに表示されます。
中身を調べていくと、この配列は8つの要素を持ち、各要素は辞書になっていて、「link」「name」「icon」 という3つのキーで、それぞれデータが記録されていることがわかります。作成したプロパティリストの内容と照合すれば、正しく読み込めていることが確認できるでしょう。
この連載の記事
- 第100回 SceneKitの物理現象シミュレーションとアニメーションをARKitに持ち込む
- 第99回 「物理学体」と「物理学場」を設定して物理現象をシミュレーション
- 第98回 SceneKitのノードに動きを加えるプログラム
- 第97回 いろいろな形のノードをシーンの中に配置する
- 第96回 SceneKitの基礎シーンビュー、シーン、ノードを理解する
- 第95回 現実世界の床にボールや自動車のモデルを配置する
- 第94回 ARKitを使って非現実世界との融合に備える
- 第93回 ARKitが使えるiPadを識別するプログラム
- 第92回 Swift Playgrounds 2.1での問題点をまとめて解消する
- 第91回 iPadの内蔵カメラで撮影した写真を認識するプログラム
- この連載の一覧へ