ユーザーデフォルトシステムについて
ユーザーデフォルトシステムは、各ユーザの環境設定の記憶域を管理します。ほとんどの環境設定は永続的に保存されるため、アプリの次の起動サイクルの間は変更されません。アプリは、ユーザーが開始し、プログラムが開始した構成変更を追跡するために環境設定を使用します。
どうすれば良い環境設定になるか?
アプリの環境設定を定義するときは、可能な限り単純な値とデータ型を使用する方がよいでしょう。環境設定システムは、文字列、数字、日付などのプロパティリストのデータ型を中心に構築されています。 NSData オブジェクトを使用して任意のオブジェクトを環境設定に格納することもできますが、ほとんどの場合、そうすることはお勧めできません。
オブジェクトを永続的に保存するということは、アプリがある時点でそのオブジェクトを復号化する必要があることを意味します。環境設定の場合、格納されたオブジェクトとは、環境設定にアクセスするたびにオブジェクトを復号化することを意味します。また、新しいバージョンのアプリとは、以前のバージョンのアプリを使用して作成されたオブジェクトをディスクに復号化できることを保証する必要があり、これはエラーが発生しやすいです。
より良い環境設定は、単純な文字列と値を格納し、それらを使用してアプリに必要なオブジェクトを作成することです。単純な値を格納するということは、アプリがいつでも値にアクセスできることを意味します。リリースからリリースに変わる唯一の事は、単純な値の解釈と、あなたのアプリがそれに応じて作成するオブジェクトです。
環境設定インタフェースの提供
ユーザー向きの環境設定については、表 1-1 に、これらの環境設定をユーザーに表示するためのオプションを一覧で示します。この表からわかるように、ほとんどのオプションには、環境設定を管理および提示するためのカスタム・ユーザー・インターフェースの作成が含まれます。iOS アプリを作成している場合は、設定バンドルを使用して環境設定を表示できますが、ユーザーが設定を滅多に変更しない場合にのみそうする必要があります。
表 1-1 ユーザーに環境設定を表示するためのオプション
環境設定 | iOS | OS X |
頻繁に変更される環境設定 | カスタム UI | カスタム UI |
滅多に変更されない環境設定 | 設定バンドル | カスタム UI |
Mac アプリの環境設定は、アプリメニューの [環境設定] メニュー項目からアクセスできる必要があります。Xcode テンプレートを使用して作成された Cocoa アプリは、このようなメニュー項目を自動的に提供します。ユーザーがこのメニュー項目を選択したときに、適切なユーザーインターフェイスを表示するのはあなたの責任です。カスタムの環境設定ウィンドウを表示し、そのアクションメソッドを Interface Builder のメニュー項目に接続するアクションメソッドをアプリのデリゲートに定義することによって、そのユーザーインターフェイスを提供できます。
iOS アプリの中からカスタムの環境設定を表示する標準的な方法はありません。Tab-Bar インターフェイスで別のタブを使用するか、アプリの画面からカスタムボタンを使用するなど、さまざまな方法で環境設定を統合できます。環境設定は、一般的に、別個のビューコントローラを使用して提示されるべきであり、それでそのビューコントローラがユーザによって却下されたときに環境設定の変更を記録することができます。
環境設定の構成
環境設定はドメインにグループ化され、それぞれのドメインには名前と特定の用途があります。たとえば、アプリ特有の環境設定用のドメインと、すべてのアプリに適用されるシステム全体の環境設定用の別のドメインがあります。すべての環境設定は、ユーザーごとに格納され、アクセスされます。ユーザー間での環境設定の共有はサポートされていません。
各環境設定には 3 つの部分があります。
- それが格納されているドメイン
- その名前 (NSString オブジェクトとして指定されています)
- その値、それは任意のプロパティリストオブジェクト(NSData、NSString、NSNumber、NSDate、NSArray、NSDictionary) でもかまいません。
環境設定の寿命は、保存するドメインによって異なります。一部のドメインは、環境設定をユーザーのデフォルトデータベースに書き込んで永続的に保存します。このような環境設定は、1 回のアプリの起動から次の起動まで存在し続けます。他のドメインは、より揮発性のある方法で環境設定を格納し、対応するユーザーのデフォルトオブジェクトの寿命期間のみ環境設定値を保持します。
特定の環境設定値の検索は、NSUserDefaults オブジェクトの検索リスト内のドメインを介して行われます。検索リスト内のドメインのみが検索され、NSArgumentDomain ドメインから始まる 表 1-2 の順に検索されます。指定した名前の環境設定が見つかると検索は終了します。複数のドメインに同じ環境設定が含まれている場合、値は検索リストの先頭に最も近いドメインから取得されます。
表 1-2 ドメインの検索順序
ドメイン | 状態 |
NSArgumentDomain | 揮発性 |
Application (アプリの ID により識別) | 永続性 |
NSGlobalDomain | 永続性 |
Languages (言語名により識別) | 揮発性 |
NSRegistrationDomain | 揮発性 |
引数ドメイン(Argument Domain)
引数ドメインは、コマンドライン引数から設定された値を含み (コマンドラインからアプリを起動した場合)、NSArgumentDomain 定数によって識別されます。コマンドラインから設定された値は、システムによって自動的にこのドメインに配置されます。このドメインに値を追加するには、コマンドライン上で (ハイフンの前に) 環境設定名を指定し、それに対応する値を続けます。たとえば、以下のコマンドは Xcode を起動し、その IndexOnOpen 環境設定値を NO に設定します。
コマンド行から設定された環境設定は、ユーザーのデフォルト・データベースに保管されている確立された値を一時的にオーバーライドします。前記の例では、IndexOnOpen 環境設定を NO に設定すると、ユーザーのデフォルト・データベースで環境設定が YES に設定されていても、Xcode がプロジェクトを自動的に索引付けする事から防ぎます。
アプリケーションドメイン
アプリケーションドメインには、現在のユーザーのユーザーデフォルトデータベースに格納されているアプリ特有の環境設定が含まれています。共有された NSUserDefaults オブジェクト (または OS X の NSUserDefaultsController オブジェクト) を使用して環境設定を書き込むと、それらの環境設定は自動的にこのドメインに配置されます。
このドメインはアプリ特有のため、ドメインの内容はアプリのバンドル ID に関連付けられています。このドメインの内容は、システムによって管理されているファイルに格納されます。現在のところ、このファイルは $ HOME/Library/Preferences/ ディレクトリにあります。ここで、$ HOME はアプリのホームディレクトリかユーザーのホームディレクトリです (プラットフォームと、アプリがサンドボックスにあるかどうかによって異なります) 。ユーザーのデフォルトデータベースファイルの名前は <ApplicationBundleIdentifer> .plist であり、ここで <ApplicationBundleIdentifer> はアプリのバンドル ID です。このファイルを直接変更するべきではありませんが、デバッグ中にこのファイルを検査して、アプリによって環境設定値が書き込まれていることを確認できます。
グローバルドメイン(Global Domain)
グローバルドメインには、すべてのアプリに適用される環境設定が含まれており、NSGlobalDomain 定数で識別されます。このドメインは通常、システム全体の値を格納するためにシステムフレームワークで使用されるため、アプリ特有の値を格納するためにアプリで使用しないでください。グローバル・ドメイン内の環境設定値を変更したい場合は、同じ環境設定をアプリケーション・ドメインに新しい値で書き込んで下さい。
システムフレームワークがこのドメインをどのように使用するかの例:
- NSRuleView クラスのインスタンスは、ユーザーの優先測定単位を AppleMeasurementUnits キーに格納します。この保存場所を使用すると、すべてのアプリでルーラー表示に同じ単位が使用されます。
- システムは、AppleLanguages キーを使用して、ユーザーの優先言語を文字列の配列として格納します。たとえば、ユーザーは、英語、スペイン語、フランス語、ドイツ語、イタリア語、スウェーデン語を優先言語として指定できます。
言語ドメイン(Language Domain)
AppleLanguages 環境設定の各言語について、システムは言語特有の環境設定値が、言語名に基づく名前であるドメイン内に記録します。各言語特有のドメインには、対応するロケールの環境設定が含まれています。Foundation フレームワークの多くのクラス (NSDate、NSDateFormatter、NSTimeZone、NSString、NSScanner クラスなど) は、このロケール情報を使用して動作を変更します。たとえば、NSCalendarDate オブジェクトの文字列表現を要求すると、NSCalendarDate オブジェクトはロケール情報を使用して、ユーザーの優先言語の月と曜日の名前を検索します。
登録ドメイン(Registration Domain)
登録ドメインは、特定の環境設定が他のドメインの 1 つに明示的に設定されていない場合に使用するデフォルト値の設定を定義します。起動時に、アプリは NSUserDefaults の registerDefaults: メソッドを呼び出して、重要な環境設定のデフォルト設定値を指定できます。アプリの初回の起動時には、ほとんどの環境設定には値がないため、それらを取得すると未定義の結果が得られます。デフォルト値の設定を登録することで、あなたのアプリは常に操作される既知の良い値の設定を持つことができます。
登録ドメインの内容は、registerDefaults: メソッドを使用することによってのみ設定できます。
デフォルトツールで環境設定の表示
OS X では、defaults のコマンドラインツールを使用すると、ユーザーのデフォルトデータベースの内容を調べることができます。アプリの開発中に、このツールを使用して、アプリがディスクに書き込む環境設定を検証できます。これを行うには、Terminal アプリから以下の形式のコマンドを使用して下さい。
defaults read <application-bundle-identifier>
グローバルドメインの内容を読み取るには、以下のコマンドを使用して下さい。
defaults read NSGlobalDomain
defaults ツールを使用して環境設定値を読み書きする方法の詳細については、defaults のマニュアルページを参照してください。