HiveBrain v1.2.0
Get Started
← Back to all entries
patternModerate

Using a Dictionary to retrieve BOOL values

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
boolretrieveusingvaluesdictionary

Problem

I have some values pulled from a web service giving me a bool value for a key. I did it this way, but feel like it is repeating without need. How can I refactor this?

Please note that the key on the dictionary has the same name as the object property.

for (NSDictionary *itemDicto in switchesArray) {
    if ([[itemDicto objectForKey:@"id"]isEqualToString:@"FindBookMeeting"]) {
        currentAppswitches.FindBookMeeting = [[itemDicto objectForKey:@"value"]boolValue];
    }
    if ([[itemDicto objectForKey:@"id"]isEqualToString:@"FindCapabilityLocate"]) {
        currentAppswitches.FindCapabilityLocate = [[itemDicto objectForKey:@"value"]boolValue];
    }
    if ([[itemDicto objectForKey:@"id"]isEqualToString:@"FindDesk"]) {
        currentAppswitches.FindDesk = [[itemDicto objectForKey:@"value"]boolValue];
    }
    if ([[itemDicto objectForKey:@"id"]isEqualToString:@"FindEmployeeLocate"]) {
        currentAppswitches.FindEmployeeLocate = [[itemDicto objectForKey:@"value"]boolValue];
    }
    if ([[itemDicto objectForKey:@"id"]isEqualToString:@"Help"]) {
        currentAppswitches.Help = [[itemDicto objectForKey:@"value"]boolValue];
    }
    if ([[itemDicto objectForKey:@"id"]isEqualToString:@"ReportProblemIT"]) {
        currentAppswitches.ReportProblemIT = [[itemDicto objectForKey:@"value"]boolValue];
        //test ok
        //currentAppswitches.ReportProblemIT = NO;
    }
    if ([[itemDicto objectForKey:@"id"]isEqualToString:@"ReportProblemProperty"]) {
        currentAppswitches.ReportProblemProperty = [[itemDicto objectForKey:@"value"]boolValue];
    }
    if ([[itemDicto objectForKey:@"id"]isEqualToString:@"Settings"]) {
        currentAppswitches.Settings = [[itemDicto objectForKey:@"value"]boolValue];
    }
}

Solution

Assuming the values under the id keys always match properties of currentAppswitches.

If you can change currentAppswitches's class to accept an NSNumber object rather than a BOOL you have some convenient options.

If currentAppswitches is KVO compliant you could write:

for (NSDictionary *item in switchesArray) {
  id value = [item objectForKey:@"value"];
  id key = [item objectForKey:@"id"];
  [currentAppswitches setValue:value forKeyPath:key];
}


Alternately you could use:

for (NSDictionary *item in switchesArray) {
  BOOL value = [[item objectForKey:@"value"] boolValue];

  //construct a selector for the property setter
  NSMutableString *selectorName = [item objectForKey:@"id"];
  NSString *firstCharacter = [selectorName substringToIndex:1];
  [selectorName stringByReplacingCharactersInRange:NSMakeRange(0,1) withString:[firstCharacter uppercaseString]];
  [selectorName insertString:@"set" atIndex:0];
  [selectorName appendString:@":"];

  SEL selector = NSSelectorFromString(selectorName);
  [currentAppswitches performSelector:selector withObject:value];
}


If currentAppswitches must continue to accept BOOLs then you could create an invocation:

for (NSDictionary *item in switchesArray) {
  id value = [item objectForKey:@"value"];

  //construct a selector for the property setter
  NSMutableString *selectorName = [item objectForKey:@"id"];
  NSString *firstCharacter = [selectorName substringToIndex:1];
  [selectorName stringByReplacingCharactersInRange:NSMakeRange(0,1) withString:[firstCharacter uppercaseString]];
  [selectorName insertString:@"set" atIndex:0];
  [selectorName appendString:@":"];

  SEL selector = NSSelectorFromString(selectorName);
  NSMethodSignature* signature = [[currentAppswitches class] instanceMethodSignatureForSelector:selector];
  NSInvocation* invocation = [NSInvocation invocationWithMethodSignature:signature];
  [invocation setTarget:currentAppswitches];
  [invocation setSelector:selector ];
  [invocation setArgument:&myBoolValue atIndex:2];
  [invocation invoke];
}

Code Snippets

for (NSDictionary *item in switchesArray) {
  id value = [item objectForKey:@"value"];
  id key = [item objectForKey:@"id"];
  [currentAppswitches setValue:value forKeyPath:key];
}
for (NSDictionary *item in switchesArray) {
  BOOL value = [[item objectForKey:@"value"] boolValue];

  //construct a selector for the property setter
  NSMutableString *selectorName = [item objectForKey:@"id"];
  NSString *firstCharacter = [selectorName substringToIndex:1];
  [selectorName stringByReplacingCharactersInRange:NSMakeRange(0,1) withString:[firstCharacter uppercaseString]];
  [selectorName insertString:@"set" atIndex:0];
  [selectorName appendString:@":"];

  SEL selector = NSSelectorFromString(selectorName);
  [currentAppswitches performSelector:selector withObject:value];
}
for (NSDictionary *item in switchesArray) {
  id value = [item objectForKey:@"value"];

  //construct a selector for the property setter
  NSMutableString *selectorName = [item objectForKey:@"id"];
  NSString *firstCharacter = [selectorName substringToIndex:1];
  [selectorName stringByReplacingCharactersInRange:NSMakeRange(0,1) withString:[firstCharacter uppercaseString]];
  [selectorName insertString:@"set" atIndex:0];
  [selectorName appendString:@":"];

  SEL selector = NSSelectorFromString(selectorName);
  NSMethodSignature* signature = [[currentAppswitches class] instanceMethodSignatureForSelector:selector];
  NSInvocation* invocation = [NSInvocation invocationWithMethodSignature:signature];
  [invocation setTarget:currentAppswitches];
  [invocation setSelector:selector ];
  [invocation setArgument:&myBoolValue atIndex:2];
  [invocation invoke];
}

Context

StackExchange Code Review Q#60657, answer score: 12

Revisions (0)

No revisions yet.