読者です 読者をやめる 読者になる 読者になる

Settings.bundle の Root.plist から Title, Value を持つ Dictionary の配列をロケールに合わせて取得する

iOS Cocoa Objective-C

Settings.bundle の Root.plist をアプリケーションに作成すると、iPhone/iPad の「設定」画面とそれによるパラメータ設定が可能になりますが、その中の PSGroupSpecifier の候補リストをアプリケーション内部から取得する方法について明記します。

設定値は、iOS のシステムロケールによって適切な Title に置き換わります。そこも同様になるように処理します。

Settings.bundle の Root.plist

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>StringsTable</key>
	<string>Root</string>
	<key>PreferenceSpecifiers</key>
	<array>
		<dict>
			<key>Type</key>
			<string>PSGroupSpecifier</string>
			<key>Title</key>
			<string>SearchTarget</string>
		</dict>
		<dict>
			<key>Values</key>
			<array>
				<string></string>
				<string>ja_JP</string>
				<string>en_US</string>
				<string>en_GB</string>
			</array>
			<key>Titles</key>
			<array>
				<string>SystemLocale</string>
				<string>Japan</string>
				<string>USA</string>
				<string>UK</string>
			</array>
		</dict>
	</array>
</dict>
</plist>

PreferenceSpecifiers / PSGroupSpecifier の取得処理

Settings.bundleの取得

まず、Settings.bundle への参照を取得します。

NSString *settingBundlePath = [[[NSBundle mainBundle] bundlePath]
                stringByAppendingPathComponent:@"Settings.bundle"];
NSBundle *settingBundle = [NSBundle bundleWithPath:settingBundlePath];
Root.plist の取得

NSBundle の pathForResource:ofType: メソッドで Root.plist を NSDictionary のインスタンスとして取得します。

NSString *rootPlistPath = [settingBundle pathForResource:@"Root" ofType:@"plist"];
NSDictionary *rootPlist = [NSDictionary dictionaryWithContentsOfFile:rootPlistPath];
PreferenceSpecifiers の値候補リストを取得

PreferenceSpecifiers は二つの要素を持ち、インデックス0は定義、インデックス1が実体なので後者の NSDictionary を取得します。
さらに値と表記のそれぞれの要素群を Values, Titles を NSArray で取得します。

NSArray *array = [rootPlist objectForKey:@"PreferenceSpecifiers"];
NSDictionary *localeItem = [array objectAtIndex:1];
		
NSArray *values = [localeItem objectForKey:@"Values"];
NSArray *titles = [localeItem objectForKey:@"Titles"];

Values, Titles の各インデックス値をペアとして NSDictionary を生成し、NSArray にまとめます。

int count = [values count];
NSMutableArray *items = [[NSMutableArray alloc] initWithCapacity:count];
for (int i = 0; i < count; i++) {
    NSMutableDictionary *newItem = [NSMutableDictionary new];
    [newItem setObject:[values objectAtIndex:i] forKey:@"value"];
    NSString *titleKey = [titles objectAtIndex:i];
    NSString *localizedTitle = [settingBundle localizedStringForKey:titleKey value:titleKey table:@"Root"];
    [newItem setObject:localizedTitle forKey:@"title"];
			
    [items addObject:newItem];
    [newItem release];
}	

Title のロケール反映値は NSBundle の localizedStringForKey:value:table: メソッドを利用して取得している。
上記の items を UITableView などで利用できる。