neowinston
neowinston

Reputation: 7764

What's the best way to store many NSDictionaries?

I need to store many Facebook App Id's and Twitter Consumer Keys for differente configurations and settings in my iPhone application.

I know the way I'm doing this is not the best one, because it has too many if else statements. What would be the best way to accomplish this task, using a correct Objective-C design pattern?

Here is my code:

- (id) init {
self = [super init];
if (!self) return nil;

keyNames = [[NSArray arrayWithObjects:
             @"facebookAppId", 
             @"facebookLocalAppId",
             @"twitterConsumerKey",
             @"twitterSecret",
             nil]retain];

if (MainLanguage == @"English") {

    keys = [[NSArray arrayWithObjects:
             @"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", //facebookAppId
             @"yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy", //facebookLocalAppId
             @"zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz", //twitterConsumerKey
             @"wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww", //twitterSecret
             nil]retain];

    dictionary = [[NSDictionary dictionaryWithObjects:keys forKeys:keyNames]retain];

}

else if (MainLanguage == @"Spanish") {

    keys = [[NSArray arrayWithObjects:
             @"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", //facebookAppId
             @"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", //facebookLocalAppId
             @"cccccccccccccccccccccccccccccccc", //twitterConsumerKey
             @"dddddddddddddddddddddddddddddddd", //twitterSecret
             nil]retain];

    dictionary = [[NSDictionary dictionaryWithObjects:keys forKeys:keyNames]retain];

}  else if (MainLanguage == @"French") {

   //etc...

} else if (MainLanguage == @"Italian") {

    //etc...

}


//etc..

return self;

}

-(void)dealloc {

    [keyNames release];
    [keys release];
    [dictionary release];
    [super dealloc];

}

Upvotes: 0

Views: 151

Answers (2)

tc.
tc.

Reputation: 33592

Two main problems:

  • Why are the key names in an array?
  • You should not be comparing NSString*s with ==.

You also probably want to be using language codes.

I can think of two "Objective-C" options, one hacky option, and one "C" option:

  1. Store it in a dictionary. This seems a little wasteful because it constructs a bunch of dictionaries and only uses one of them.

    [NSDictionary dictionaryWithObjectsAndKeys:
      [NSDictionary dictionaryWithObjectsAndKeys:
        @"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", @"facebookAppId",
        @"yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy", @"facebookLocalAppId",
        ...
      nil], @"en",
      [NSDictionary dictionaryWithObjectsAndKeys:
        @"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", @"facebookAppId",
        ...
      nil], @"es",
      ...
    nil]
    
  2. Stick it a dictionary in a plist. This might be problematic, because all someone has to do to extract them is unzip your .ipa.

    <dict>
      <key>en</key>
      <dict>
        <key>facebookAppId</key>
        <string>...</string>
        ...
      </dict>
      <key>es</key>
      <dict>
        ...
      </dict>
      ...
    </dict>
    
  3. Store it in Localizable.strings. Again, trivial to extract by unzipping the .ipa.

  4. Store it in an array of structs:

    struct {
      NSString *lang;
      NSString *facebookAppId;
      NSString *facebookLocalAppId;
      NSString *twitterConsumerKey;
      NSString *twitterConsumerSecret;
    } const foo_data[] = {
      {@"en", @"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", @"yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy", ...},
      {@"es", @"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", ...},
      ...
    };
    
    ...
    
    for (size_t i = 0; i < sizeof(foo_data)/sizeof(foo_data[0]); i++) {
      if ([lang isEqualToString:foo_data[i].lang]) {
        return [NSDictionary dictionaryWithObjectsAndKeys:
                 foo_data[i].facebookAppId,@"facebookAppId",
                 ...
               nil];
      }
    }
    

Upvotes: 1

user1486722
user1486722

Reputation:

Well the data has to be stored somewhere right? You could have a separate class that stores the data in a hash table. Then you just need to reference that able each time you get a language. Your code will definitely look cleaner. Check out NSHashTable.

Upvotes: 0

Related Questions