コマンドラインツールで設定ファイルを使う方法

いろいろあると思うけど、実行ファイルと同じディレクトリ(またはその下のResourceディレクトリ)に.plistファイルが配置されるようにして、NSBundleの-pathForResource:ofType:で引っ張ってくるのが楽な気がする。

ファイル(Config.plist)の内容

{
    /* database connection configuration */
    connectionDictionary = {
        dbname = "hatebu";
        host = "localhost";
        port = "5432";
        user = "postgres";
    };
    tableInfos = {
        hatebu_user = {
            tableName = "hatebu_user";
            primaryKeyNames = ("record_id");
        };
        hatebu_favorite = {
            tableName = "hatebu_favorite";
            primaryKeyNames = ("src_id", "dest_id");
        };
    };
    /* Crawling URL */
    hotentryRSSURL = "http://b.hatena.ne.jp/hotentry?mode=rss";
    entryRSSURLFormat = "http://b.hatena.ne.jp/entry/rss/%@";
    favoriteHTMLURLFormat = "http://b.hatena.ne.jp/%@/favorite";
}

ProjectBuilderでの設定方法

  1. プロジェクトディレクトリ下にResourcesというディレクトリを作成。その下にConfig.plistを保存。
  2. プロジェクト下で右クリック→「追加」→「既存のファイル」で上のResourcesディレクトリを選択して「追加」
  3. 「グループとファイル」(左側のカラム)で右クリック→「新規ビルドフェーズ」→「新規コピーファイル・ビルドフェーズ」を選ぶ。ターゲット内に「ファイルをコピー」がもう一つ追加される。
  4. 「ファイルをコピー」のインスペクタを開き、下位パスを「Contents/Resources」に設定
  5. 「グループとファイル」で2.で追加したResourcesディレクトリ内の設定ファイル(Config.plist)を3.のビルドフェーズにドラッグ&ドロップする。

これでビルド時にbuildディレクトリの下にContents/Resources/というディレクトリが出来、その中にConfig.plistがコピーされるようになる。install時はバイナリファイルと同じ階層にContentsフォルダが出来る。4.を省略すると、バイナリファイルと同階層にConfig.plistが出来る。

プログラムから設定値の内容を取得

main関数などで以下のように記述し、設定ファイルの値を読み込む。

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    // Configuration
    NSDictionary *configuration = nil;
    // mailBundleからパスを取得
    NSString *configurationPath =
        [[NSBundle mainBundle] pathForResource:CONFIGURATION_FILENAME ofType:CONFIGURATION_EXT];

    if (configurationPath) {
        // NSDictionaryとしてファイルの内容を読み込む
        configuration = [NSDictionary dictionaryWithContentsOfFile:configurationPath];
        NSLog(@"configuration = %@", configuration);

        // NSUserDefaultsにデフォルト時の値として登録
        [[NSUserDefaults standardUserDefaults] registerDefaults:configuration];
    }
        
    // your code...
    
    [pool release];
}

この例ではNSUserDefaultsにregisterDefaultsで登録している。こうしておくと、ファイルを変更しなくてもdefaultsコマンド(defaults write)で設定値の一部だけを上書きできる。


設定値を使用する側の例

#define CONNECTION_DICTIONARY_KEY @"connectionDictionary"
....
- (NSDictionary *)connectionDictionary
{
    NSDictionary *connectionDictionary =
        [[NSUserDefaults standardUserDefaults] dictionaryForKey:CONNECTION_DICTIONARY_KEY];
    if (!connectionDictionary) {
        raiseConfigException(CONNECTION_DICTIONARY_KEY);
    }
    return connectionDictionary;
    
}