0

I have the following Model:

@interface Person : NSObject

@property (nonatomic, copy) NSString *firstName;
@property (nonatomic, copy) NSString *middleName;
@property (nonatomic, copy) NSString *lastName;
@property (nonatomic, copy) NSString *status;
@property (nonatomic, copy) NSString *favoriteMeal;
@property (nonatomic, copy) NSString *favoriteDrink;
@property (nonatomic, copy) NSString *favoriteShow;
@property (nonatomic, copy) NSString *favoriteMovie;
@property (nonatomic, copy) NSString *favoriteSport; 

-(NSDictionary *)getSomeInfo;
-(NSDictionary *)getAllInfo;

@end

Part 1: I want getSomeInfo to return NSDictionary (e.g. {"firstName", self.firstName}) for all the fields that does not contain nil. How can I do that? (I could check every value but I wonder if there's a better way)

Part 2: I want getAllInfo to return NSDictionary with all the property and if one contains nil then it should throw an error. Again do I have to write a long conditional statement to check or is there a better way?

Note: I want to do this without using external library. I'm new to the language so I'm open to suggestions if there's a better pattern in Objective-C.

Jimmy
  • 10,427
  • 18
  • 67
  • 122
  • Have a look at http://stackoverflow.com/a/2302808/550672 to get you started – Zeophlite Jul 15 '13 at 22:47
  • Or `dictionaryWithVakuesForKeys:`. – Wain Jul 15 '13 at 22:50
  • Exceptions are usually reserved for non-recoverable errors in Objective-C (meaning an exit should occur soon after), unlike languages like Java and Python. Consider using an NSError as an out parameter, or even just making the value in the dictionary an `[NSNull null]`. – Kitsune Jul 16 '13 at 00:21
  • @Kitsune Thanks for pointing this out, I'll defiantly read more about it. – Jimmy Jul 16 '13 at 17:47

1 Answers1

1

There are two approaches.

1) Check each value:

- (NSDictionary *)getSomeInfo {
    NSMutableDictionary *res = [NSMutableDictionary dictionary];

    if (self.firstName.length) {
        res[@"firstName"] = self.firstName;
    }
    if (self.middleName.length) {
        res[@"middleName"] = self.middleName;
    }
    // Repeat for all of the properties

    return res;
}

2) Use KVC (Key-value coding):

- (NSDictionary *)getSomeInfo {
    NSMutableDictionary *res = [NSMutableDictionary dictionary];

    NSArray *properties = @[ @"firstName", @"middleName", @"lastName", ... ]; // list all of the properties
    for (NSString *property in properties) {
        NSString *value = [self valueForKey:property];
        if (value.length) {
            res[property] = value;
        }
    }

    return res;
}

For the getAllInfo method you can do the same but instead return nil if any value is missing. Treat the nil results as your indication that not all properties have a value.

rmaddy
  • 314,917
  • 42
  • 532
  • 579
  • Oh man! when I start reading about KVC I was like this is exactly what I was looking for. It really cuts a lot of the boilerplate code. Thanks! – Jimmy Jul 16 '13 at 17:45