2011-07-12 9 views
5

InAppSettingsKitモジュールを使用して設定を管理しています。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]でこう言っています。

答えて

6

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

初めてアプリを起動すると、userDefaultsはありません。通常、あなたのリソースからの静的userDefaults.plistで読み取ることにより、適切なデフォルトの設定値を設定することで起動します。それはすべての今感を作って

// 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]; 
+0

+1私は似たようなものを投稿しようとしていましたが、これはすでに上がっていました!あなたはこれを受け入れるべきです:) – Sum

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]; 
     } 
} 
+0

一見したところでは、コードはOKです。しかし、 'Root.plist'ではなく、別のファイルで指定された子ペインがあれば動作しません。 –

+0

'[[iaskSettingsViewController settingsReader] settingsBundle]'を使用して上記のコード – Sam

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]; 

}

2

をsubclass-私は別のファイルに指定された子ペインを処理するために、サムのコードを変更:

#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]; 
} 
+0

+1で適切なpreferencesArrayを取得することができます。とても良い! ARCのコード会計を少し修正しました。 –

4

ここで、オハスのコードは、ARCの説明に少し変更されています。

おそらく、あなたの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]; 
} 
+0

これはGitHub https://github.com/futuretap/InAppSettingsKit/issues/68に掲載された問題に関連しているようです –

1

私は@Ojasで与えられた答えに基づいています。しかし私はそれを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() 
    } 
} 
関連する問題