Saturday, April 15, 2017

How to avoid building apps that crash by parsing JSON (Objective C)

April 15, 2017 Posted by CHANDAN MAKHIJA No comments
When you’re just getting started with Objective C, it’s easy to fall into the trap of doing things the easy way, especially when working with JSON. But if you parse JSON the easy way, your app will crash, and you’ll be scratching your head wondering why. For your users and for your own sanity, don’t build apps that crash – be sure that when you parse JSON, you do it the safe way, not the easy way.

Let’s start with some simple JSON we’d like to parse:



{
"data": [ {"name":"chandan"},
          {"name":"vipul"}
         ]
}




You will parse this JSON like


NSArray* array = [dict objectForKey@"data"];



And you will receive a array of dictionary in "array". But now imagine a situation when a key "data" is now not containing an array or a key has been changed. Now what will happen, your APP will get crashed because it has not found an array. So to avoid these kind of crashes just create a category of your dictionary and add some methods as shown below.




#import "NSDictionary+RMDictionary.h"

@implementation NSDictionary (RMDictionary)

- (BOOL) boolForKey:(NSString*)aKey
{
    NSObject* value = [self valueForKey:aKey];
    if ([value isKindOfClass:[NSNumber class]])
    {
        NSNumber* num = (NSNumber*)value;
        return num.boolValue;
        
    }
    else
        return NO;
}

- (NSInteger) integerForKey:(NSString*)key
{
    NSObject* value = [self valueForKey:key];
    if ([value isKindOfClass:[NSNumber class]])
    {
        return ((NSNumber*)value).integerValue;
    }
    return 0;
}

- (NSString*) stringForKey:(NSString*)key
{
    id value = [self valueForKey:key];
    
    if ([value isKindOfClass:[NSString class]])
    {
        return (NSString*)value;
    }
    return @"";
}

- (NSDate*) dateForKey:(NSString*)key
{
    NSString* value = [self stringForKey:key];
    NSDateFormatter* formatter = [[NSDateFormatter alloc]init];
    [formatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss"];
    NSDate* date = [formatter dateFromString:value];
    
    if (date)
    {
        return date;
    }
    
    return [NSDate dateWithTimeIntervalSince1970:0];
}

-(NSArray*) arrayForKey:(NSString*)key
{
    id value = [self valueForKey:key];
    if([value isKindOfClass:[NSArray class]])
    {
        return (NSArray*)value;
    }
    return [[NSArray alloc] init];
}

- (NSNumber*) numberForKey:(NSString*)key
{
    NSObject* value = [self valueForKey:key];
    if ([value isKindOfClass:[NSNumber class]])
    {
        return (NSNumber*)value;
    }
    return 0;
}

- (NSDictionary*) dictionaryForKey:(NSString*)key
{
    id value = [self valueForKey:key];
    if([value isKindOfClass:[NSDictionary class]])
    {
        return (NSDictionary*)value;
    }
    return [[NSDictionary alloc] init];
}


@end




Now instead of using "objectForKey" start using "arrayForKey" or "stringForKey". This will now avoid your APP crash, because if array is not found it will create an empty array and then return.

  

0 comments:

Post a Comment