5

InAppSettingsKitモジュールを使用して設定を管理しています。

プロジェクトと正しくやり取りする設定ページを作成できるようになるまで、プロジェクトに含めることができます。変更できる root.plist があり、シミュレーターでアプリを初めて実行すると、変更が反映されていることがわかります。

ただし、私の人生ではNSUserDefaults、コードから設定にアクセスすることはできません。以下のコードを実行すると、 の内容をループできます[NSUserDefaults standardUserDefaults]。ただし、plist ファイル内のものとは関係のない一般的な設定のみが表示されます

NSUserDefaults* d = [NSUserDefaults standardUserDefaults];

NSDictionary* dict = [d dictionaryRepresentation];

NSString* descKey;
NSString* descObject;
NSString* classTypeForKey;
NSString* classTypeForObject;
id myObject;

for (id key in dict) {
    myObject = [dict objectForKey:key];
    classTypeForObject = [[myObject class] description];
    classTypeForKey = [[key class] description];
    descKey = [key description];
    descObject = [myObject description];
}

では、InAppSettingsKit はどこに設定を配置するのでしょうか? 医者が言う[NSUserDefaults standardUserDefaults]ので、私は途方に暮れています。

4

6 に答える 6

6

あなたの問題は、概念の誤解に依存していると思います。Root.plist は設定を保存しませんが、Settings.app と InAppSettingsKit が userDefaults でどのように機能するかを定義するだけです。

アプリの初回起動時には、userDefaults はありません。userDefaults.plist通常、リソースからstatic を読み込んで、適切なデフォルト設定を設定することから始めます。

// Load the default values for the user defaults
NSString* pathToUserDefaultsValues = [[NSBundle mainBundle]
                                      pathForResource:@"userDefaults" 
                                      ofType:@"plist"];
NSDictionary* userDefaultsValues = [NSDictionary dictionaryWithContentsOfFile:pathToUserDefaultsValues];

// Set them in the standard user defaults
[[NSUserDefaults standardUserDefaults] registerDefaults:userDefaultsValues];
于 2011-07-12T23:00:20.443 に答える
4

これは、ARC を説明するためにもう少し修正された Ojas のコードです。

おそらく AppDelegate didFinishLaunchingWithOptions から initializeSettings を呼び出すでしょう。

#import "IASKSettingsReader.h"
...

- (void)initializeSettings
{
    // standard stored preference values
    NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];

    // settings files to process
    NSMutableArray *preferenceFiles = [[NSMutableArray alloc] init];

    // begin with Root file
    [preferenceFiles addObject:@"Root"];

    // as other settings files are discovered will be added to preferencesFiles
    while ([preferenceFiles count] > 0) {

        // init IASKSettingsReader for current settings file
        NSString *file = [preferenceFiles lastObject];
        [preferenceFiles removeLastObject];
        IASKSettingsReader *settingsReader = [[IASKSettingsReader alloc]
                                              initWithFile:file];

        // extract preference specifiers
        NSArray *preferenceSpecifiers = [[settingsReader settingsBundle]
                                         objectForKey:kIASKPreferenceSpecifiers];

        // process each specifier in the current settings file
        for (NSDictionary *specifier in preferenceSpecifiers) {

            // get type of current specifier
            NSString *type = [specifier objectForKey:kIASKType];

            // need to check child pane specifier for additional file
            if ([type isEqualToString:kIASKPSChildPaneSpecifier]) {
                [preferenceFiles addObject:[specifier objectForKey:kIASKFile]];
            }
            else {
                // check if current specifier has a default value
                id defaultValue = [specifier objectForKey:kIASKDefaultValue];

                if (defaultValue) {
                    // get key from specifier and current stored preference value
                    NSString *key = [specifier objectForKey:kIASKKey];
                    id value = [defaults objectForKey:key];

                    // update preference value with default value if necessary
                    if (key && value == nil) {
                        [defaults setObject:defaultValue forKey:key];
                    }
                }
            }

        }

    }

    // synchronize stored preference values
    [defaults synchronize];
}
于 2012-10-10T14:11:34.383 に答える
3

今ではすべてが理にかなっています。以前の試行でデフォルトを登録して機能させようとしましたが、Root.plist ファイルを使用してこれを行うことができると思いました。しかしもちろん、registerDefaults メソッドは StringsTable と PreferenceSpecifiers の高レベルのエントリを参照するだけです。これを指摘してくれてありがとう Ortwin.

そのため、別の userDefault.plist ファイルを作成する代わりに、root.plist ファイルを解析してデフォルトを NSUserDefaults に手動で追加する次のコードを見つけました。どこで手に入れたのか覚えていませんが、うまく機能しているようです。このようにしてはいけない理由がある場合は、遠慮なく詳しく説明してください。

    - (void)setDefaults {

        //get the plist location from the settings bundle
        NSString *settingsPath = [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:@"Settings.bundle"];
        NSString *plistPath = [settingsPath stringByAppendingPathComponent:@"Root.plist"];

        //get the preference specifiers array which contains the settings
        NSDictionary *settingsDictionary = [NSDictionary dictionaryWithContentsOfFile:plistPath];
        NSArray *preferencesArray = [settingsDictionary objectForKey:@"PreferenceSpecifiers"];

        //use the shared defaults object
        NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];

        //for each preference item, set its default if there is no value set
        for(NSDictionary *item in preferencesArray) {

            //get the item key, if there is no key then we can skip it
            NSString *key = [item objectForKey:@"Key"];
            if (key) {

                //check to see if the value and default value are set
                //if a default value exists and the value is not set, use the default
                id value = [defaults objectForKey:key];
                id defaultValue = [item objectForKey:@"DefaultValue"];
                if(defaultValue && !value) {
                    [defaults setObject:defaultValue forKey:key];
                }
            }
        }

        //write the changes to disk
        [defaults synchronize];
        }
}
于 2011-07-15T00:02:50.343 に答える
2

別のファイルで指定された子ペインを処理するように Sam のコードを変更しました。

#import "IASKSettingsReader.h"

- (void)initializeSettings
{
    // standard stored preference values
    NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];

    // settings files to process
    NSMutableArray *preferenceFiles = [[NSMutableArray alloc] init];

    // begin with Root file
    [preferenceFiles addObject:@"Root"];

    // as other settings files are discovered will be added to preferencesFiles
    while (![preferenceFiles isEmpty]) {

        // init IASKSettingsReader for current settings file
        NSString *file = [[preferenceFiles lastObject] retain];
        [preferenceFiles removeLastObject];
        IASKSettingsReader *settingsReader = [[IASKSettingsReader alloc]
                                              initWithFile:file];
        [file release];

        // extract preference specifiers
        NSArray *preferenceSpecifiers = [[settingsReader settingsBundle] 
                                         objectForKey:kIASKPreferenceSpecifiers]; 

        // process each specifier in the current settings file
        for (NSDictionary *specifier in preferenceSpecifiers) {

            // get type of current specifier
            NSString *type = [specifier objectForKey:kIASKType];

            // need to check child pane specifier for additional file
            if ([type isEqualToString:kIASKPSChildPaneSpecifier]) {
                [preferenceFiles addObject:[specifier objectForKey:kIASKFile]];
            }
            else {
                // check if current specifier has a default value
                id defaultValue = [specifier objectForKey:kIASKDefaultValue];

                if (defaultValue) {
                    // get key from specifier and current stored preference value
                    NSString *key = [specifier objectForKey:kIASKKey];
                    id value = [defaults objectForKey:key];

                    // update preference value with default value if necessary
                    if (key && value == nil) {
                        [defaults setObject:defaultValue forKey:key];                        
                    }
                }
            }

        }

        [settingsReader release];
    }

    [preferenceFiles release];

    // synchornize stored preference values
    [defaults synchronize];
}
于 2012-02-12T22:58:45.933 に答える
1

@Ojasから提供された回答に基づいて回答しました。しかし、私はそれをSwiftに変換しました。これがSwiftを使用している人々に役立つことを願っています

func processDefaultSettings() {

    let defaults = IASKSettingsStoreUserDefaults().defaults

    // settings files to process
    var preferenceFiles = [String]()

    // begin with Root file
    preferenceFiles.append("Root")

    // as other settings files are discovered will be added to preferencesFiles
    while !preferenceFiles.isEmpty {

        // init IASKSettingsReader for current settings file
        let file = preferenceFiles.last
        let settingsReader = IASKSettingsReader(file: file)
        preferenceFiles.removeLast()

        // extract preference specifiers
        if let preferenceSpecfiers = settingsReader.settingsDictionary[kIASKPreferenceSpecifiers] as? NSArray {

            // process each specifier in the current settings file
            for specifier in preferenceSpecfiers {

                // get type of current specifier
                let type = specifier[kIASKType] as! String

                // need to check child pane specifier for additional file
                if type == kIASKPSChildPaneSpecifier {
                    preferenceFiles.append(specifier[kIASKFile] as! String)
                }
                else {
                    // check if current specifier has a default value
                    if let defaultValue = specifier[kIASKDefaultValue] as AnyObject? {

                        // get key from specifier and current stored preference value
                        if let key = specifier[kIASKKey] as? String {

                            if let value = defaults.objectForKey(key) {
                                // Nothing to do - already set
                            }
                            else {
                                let appDefaults = [key: defaultValue]
                                defaults.registerDefaults(appDefaults)
                            }
                        }
                    }
                }
            }
        }
        // synchornize stored preference values
        defaults.synchronize()
    }
}
于 2015-07-18T15:13:40.870 に答える
0

上記の彼自身の質問に対するスティーブの答えを修正しましたが、次のことがうまくいくようです:

あなたのIASKAppSettingsViewControllerサブクラスで-

- (void)viewDidLoad
{
    [super viewDidLoad];


    NSDictionary* settingsBundle = [self.settingsReader settingsBundle];
    NSArray *preferencesArray = [settingsBundle objectForKey:@"PreferenceSpecifiers"];
    NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];

    //for each preference item, set its default if there is no value set
    for(NSDictionary *item in preferencesArray) {

        //get the item key, if there is no key then we can skip it
        NSString *key = [item objectForKey:@"Key"];
        if (key) {

            //check to see if the value and default value are set
            //if a default value exists and the value is not set, use the default
            id value = [defaults objectForKey:key];
            id defaultValue = [item objectForKey:@"DefaultValue"];
            if(defaultValue && !value) {
                [defaults setObject:defaultValue forKey:key];
            }
        }
    }

    //write the changes to disk
    [defaults synchronize];

}

于 2012-02-01T11:56:18.777 に答える