PreferenceBundleで同じリストの管理をしやすく

■PreferenceLoaderでのリスト選択について

PreferenceLoaderのplistでリスト選択させたい場合、大抵は下記のようにして
PSListItemsControllerクラスにvalidValuesとvalidTitlesのArrayを書いてあげれば良いので非常に楽です。
detail
PSListItemsController
validValues

    80
    100
    120
    160
    200

validTitles

    80(default)
    100
    120
    160
    200(insensitive)
が、このリストへのリンクが1つ2つならまだ平気ですが、10個とかになると億劫になってきて、
追加や削除が面倒なことうけあいです。

PreferenceBundleにするとこの辺りは非常に楽になります。

■まずはBundleへ誘導するPreferenceLoader用のplistを作成

entry.plistを作成します。detailが自作するクラス名になります。
{
 entry = {
  bundle = "SleipnizerSettings";
  cell = PSLinkCell;
  detail = "RootPreferenceController";
  icon = "SleipnizerforSafari.png";
  isController = 1;
  label = "Sleipnizer for Safari";
 };
}

このentry.plistはMakefileの記述でビルド時に適切にリネーム・移動します。

BUNDLE_NAME = SleipnizerSettings
SleipnizerSettings_FILES = Preference.m
SleipnizerSettings_INSTALL_PATH = /Library/PreferenceBundles
SleipnizerSettings_FRAMEWORKS = UIKit
SleipnizerSettings_PRIVATE_FRAMEWORKS = Preferences

include $(THEOS_MAKE_PATH)/bundle.mk

internal-stage::
 $(ECHO_NOTHING)mkdir -p $(THEOS_STAGING_DIR)/Library/PreferenceLoader/Preferences$(ECHO_END)
 $(ECHO_NOTHING)cp entry.plist $(THEOS_STAGING_DIR)/Library/PreferenceLoader/Preferences/SleipnizerforSafari.plist$(ECHO_END)

■今までPreferenceLoader用に記述していたplistを読み込む

今まで記述していたPreferenceLoader用のplistがそのまま使えますので、
Bundle用の格納ディレクトリであるResourcesの中に放り込みます。

放り込んだplistを読むために以下のメソッドを書いておきます。ここでのクラス名がentry.plistのdetailに記述したものと同一になるようにします。loadSpecifiersFromPlistNameの引数はplistの名前を書きます。

#import <Preferences/Preferences.h>

__attribute__((visibility("hidden")))
@interface RootPreferenceController : PSListController
@end

@implementation RootPreferenceController
- (id)specifiers {
  if(_specifiers == nil) {
    _specifiers = [[self loadSpecifiersFromPlistName:@"SleipnizerforSafari" target:self] retain];
  }
  return _specifiers;
}
@end

これでこれまでと同じ状態に出来ました。

■リスト用のメソッドを指定する

PreferenceLoader用のkeyの中に、そのためのものがあります。valuesDataSourceとtitlesDataSourceです。
冒頭のこれまで長々と書いていた部分を置き換えます。

detail
PSListItemsController
valuesDataSource
valuesSource:
titlesDataSource
titlesSource:

■メソッドを記述する

NSArray *を返すように記述してあげます。

- (NSArray *)valuesSource:(id)target {
  return [NSArray arrayWithObjects:@"80", @"100", @"120", @"160", @"200", nil];
}

- (NSArray *)titlesSource:(id)target {
  return [NSArray arrayWithObjects:@"80(default)", @"100", @"120", @"160", @"200(insensitive)", nil];
}

これでリストを編集したければ、こちらのコードを弄れば参照箇所全てに反映されます。