 
Xamarin逆引きTips
Xamarin.iOS/Androidでアプリの設定情報を保存するには?
iOSのNSUserDefaultsやAndroidのSharedPreferenceではなく.NETのIsolatedStorageを使って、Xamarin.iOS/Androidでアプリの軽量データを保存する方法を解説する。
 アプリケーションの設定情報など、軽量なデータを保存する方法は、iOSではNSUserDefaults、AndroidではSharedPreferenceが一般的に使用される。今回は、これらをXamarin.iOS/Androidで使用する方法、また同様の機能を提供する共通なAPIについて解説する。
1iOSアプリでの設定ファイルの保存
 Xamarin.iOSではNSUserDefaultsクラスを使用する。
 NSUserDefaultsを用いたデータの保存は、以下のようになる。
| var prefs = NSUserDefaults.StandardUserDefaults; prefs.SetString("YAMADA Taro", "person_name"); prefs.SetInt(29, "person_age"); prefs.Synchronize(); | 
保存されたデータを読み出すコードは、以下のようになる。
| var prefs = NSUserDefaults.StandardUserDefaults; var parsonName = prefs.StringForKey("person_name"); var parsonAge = prefs.IntForKey("person_age"); | 
このようにして保存したデータは、アプリケーションのデータ領域に格納される。iOSシミュレーターでは、以下のようなパスになる。実際にその場所にあるファイルをテキストエディターで見てみると、確かに保存されていることが確認できる。
  /Users/<Macユーザー名>/Library/Developer/CoreSimulator/Devices/<シミュレーターのGUID>/data/Containers/Data/Application/<アプリのGUID>/Library/Preferences
2Androidアプリでの設定ファイルの保存
 Xamarin.AndroidではSharedPreferenceクラスを使用する。
 SharedPreferenceを用いたデータの保存は、以下のようになる。
| var prefs = context.GetSharedPreferences("pref", FileCreationMode.Private); var editor = prefs.Edit(); editor.PutString("person_name", "KATO Hanako"); editor.PutInt("person_age", 24); editor.Commit(); | 
※上記のcontextは、Contextクラスのオブジェクトである。ActivityクラスはこのContextクラスのサブクラスになっているので、ActivityクラスのOnCreateメソッド内などでは、context.の部分はthis.もしくは省略して記述できる。
保存されたデータを読み出すコードは、以下のようになる。
| var prefs = context.GetSharedPreferences("pref", FileCreationMode.Private); var personName = prefs.GetString("person_name", ""); var personAge = prefs.GetInt("person_age", 0); | 
Androidでの設定情報の保存先は、以下の場所だ。エミュレーターでは、下記にアクセスできるので、ファイルを開いてみると、確かに保存されていることが確認できる。
  /data/data/<アプリのパッケージ名>/shared_prefs/pref.xml
3IsolatedStorageによるiOS/Androidで共通な設定ファイルの保存
 IsolatedStorageFileクラス(System.IO.IsolatedStorage名前空間)を使うと、12で解説した設定ファイルの保存処理を共通化できる。
 IsolatedStorageとは、「分離ストレージ」と呼ばれる通常とは「分離された」記憶領域のことで、.NET Frameworkで古くから実装されている機能だ。.NETにおける分離ストレージについては、以下が詳しい。
 「分離ストレージ」は、Xamarin.iOS/Androidでは「アプリケーション固有の」という意味で実装されているようで、IsolatedStorageFileは、NSUserDefaultsやSharedPreferenceと同じような使い方ができる。
 IsolatedStorageFileだけでは、12のようなKey-Value型の形式を提供しないので、ここではJSONを使用することにする。XamarinでのJSONの使用は「Tips: Xamarin.iOS/AndroidでJSONを扱うには?(Json.NET使用)」で解説したので、参照してほしい。以下は、Json.NETパッケージが導入済みとして解説する。
データクラスの作成
 まず、設定ファイルの項目を示すデータクラスPersonを以下のように準備する。
| public class Person {   public string PersonName   {     get;     set;   }   public int PersonAge   {     get;     set;   } } | 
iOS/Androidアプリでの利用例
 IsolatedStorageFileを使ったアプリでのコード例は以下の通りだ。iOSもAndroidでも共通のコードだ。
| using Newtonsoft.Json; using System.IO.IsolatedStorage; using System.IO; ……省略…… var json = JsonConvert.SerializeObject(new Person() //<-1 {   Name = "YAMADA Taro",   Age = 29 }); var file = IsolatedStorageFile.GetUserStoreForApplication(); //<-2 using (IsolatedStorageFileStream strm = file.CreateFile("pref.json")) //<-3 using (StreamWriter writer = new StreamWriter(strm)) {   writer.Write(json); //<-4 } | 
 1は、Personデータクラスを生成し、JSON文字列に変換する処理だ。
 2で、分離ストレージを取得し、3で分離ストレージ内にファイルpref.jsonを作成する処理だ。そして4で、JSON文字列をファイルに書き出している。
反対に、設定ファイルから読み出すコードは以下のようになる。
| var file = IsolatedStorageFile.GetUserStoreForApplication(); using (IsolatedStorageFileStream strm = file.OpenFile("pref.json", FileMode.Open)) using (StreamReader reader = new StreamReader(strm)) {   var person = JsonConvert.DeserializeObject<Person>(reader.ReadToEnd());   System.Diagnostics.Debug.WriteLine(person.Name + ", " + person.Age.ToString()); } | 
 IsolatedStorageFileで保存したファイルは、
- iOSの場合:
 Application/<アプリのGUID>/Documents/.config/.isolated-storage
- Androidの場合:
 /data/data/<アプリのパッケージ名>/files/.config/.isolated-storage
に、それぞれ保存される。iOSシミュレーターやAndroidエミュレーターでは、上記の場所にあるpref.jsonファイルを開けるので、テキストエディターで見てみると、
| {"Name":"YAMADA Taro","Age":29} | 
という、PersonクラスのオブジェクトがJSON化された文字列として確認できる。
まとめ
 Xamarin.iOS/Androidでの設定ファイルの保存は、ネイティブAPI(NSUserDefaultsやSharedPreference)でも可能だが、System.IO.IsolatedStorage.IsolatedStorageFileで共通化できる。
残念ながらこのクラスも、PCL(Portable Class Library)では使用できないのでリンクファイル(「Tips: Xamarin.iOS/Androidでソースコードを共有するには?(リンクファイル編)」参照)を使用することになる。
最後に注意点として、今回解説したいずれの方法も、秘匿情報(パスワードや秘密鍵など)を保存することは推奨されていない。データが格納されるのはそのアプリにしかアクセスできない領域ではあるものの、データ自体が暗号化されているわけではないので、例えば、端末のROOT権限を所有している場合には、簡単に内容を参照することができてしまう。アプリの設定値など、漏れても害のない情報にとどめるべきだろう。
※以下では、本稿の前後を合わせて5回分(第28回~第32回)のみ表示しています。
 連載の全タイトルを参照するには、[この記事の連載 INDEX]を参照してください。
 
28. Xamarin.iOS/AndroidでJSONを扱うには?(Json.NET使用)
Web APIにおけるデータフォーマットの定番になっているJSONを、Xamarin.iOS/Androidで扱うには? 「Json.NET」というライブラリを使う方法を説明する。
 
29. Xamarin.iOS/Androidでアプリのデータディレクトリを取得するには?
アプリ固有のデータ領域のディレクトリパスを取得するため方法のうち、iOS/Androidで共通のコードの書き方を説明する。
 
30. 【現在、表示中】≫ Xamarin.iOS/Androidでアプリの設定情報を保存するには?
iOSのNSUserDefaultsやAndroidのSharedPreferenceではなく.NETのIsolatedStorageを使って、Xamarin.iOS/Androidでアプリの軽量データを保存する方法を解説する。
 
31. Xamarin.AndroidでApplicationクラスを拡張するには?
Applicationクラスを拡張すると、アプリケーションイベントの発生時に独自の処理を実行したり、アプリケーションオブジェクトに機能を追加したりできる。その基本的な実装方法を解説する。
 
32. Xamarin.iOSでZipファイルを使用するには?(ZipFileクラス編)
iOSアプリ開発標準のZipArchiveライブラリではなく、.NET標準のZipFileクラス編を使って、ZIPファイルの圧縮・展開を行う方法を解説する。






