Replace all NSNull objects in an NSDictionary
I've made a few changes to Jacob's original answer to extend it to handle dictionaries and arrays stored within the original dictionary.
#import "NSDictionary+NullReplacement.h"#import "NSArray+NullReplacement.h"@implementation NSDictionary (NullReplacement)- (NSDictionary *)dictionaryByReplacingNullsWithBlanks { const NSMutableDictionary *replaced = [self mutableCopy]; const id nul = [NSNull null]; const NSString *blank = @""; for (NSString *key in self) { id object = [self objectForKey:key]; if (object == nul) [replaced setObject:blank forKey:key]; else if ([object isKindOfClass:[NSDictionary class]]) [replaced setObject:[object dictionaryByReplacingNullsWithBlanks] forKey:key]; else if ([object isKindOfClass:[NSArray class]]) [replaced setObject:[object arrayByReplacingNullsWithBlanks] forKey:key]; } return [NSDictionary dictionaryWithDictionary:[replaced copy]];}@end
And there's also an array category of course:
#import "NSArray+NullReplacement.h"#import "NSDictionary+NullReplacement.h"@implementation NSArray (NullReplacement)- (NSArray *)arrayByReplacingNullsWithBlanks { NSMutableArray *replaced = [self mutableCopy]; const id nul = [NSNull null]; const NSString *blank = @""; for (int idx = 0; idx < [replaced count]; idx++) { id object = [replaced objectAtIndex:idx]; if (object == nul) [replaced replaceObjectAtIndex:idx withObject:blank]; else if ([object isKindOfClass:[NSDictionary class]]) [replaced replaceObjectAtIndex:idx withObject:[object dictionaryByReplacingNullsWithBlanks]]; else if ([object isKindOfClass:[NSArray class]]) [replaced replaceObjectAtIndex:idx withObject:[object arrayByReplacingNullsWithBlanks]]; } return [replaced copy];}@end
With this, you can take any array or dictionary and recursively wipe out all the [NSNull null] instances.
P.S. For completion's sake, here are the header files:
@interface NSDictionary (NullReplacement)- (NSDictionary *)dictionaryByReplacingNullsWithBlanks;@end
And the array header:
@interface NSArray (NullReplacement)- (NSArray *)arrayByReplacingNullsWithBlanks;@end
Really simple:
@interface NSDictionary (JRAdditions)- (NSDictionary *)dictionaryByReplacingNullsWithStrings;@end@implementation NSDictionary (JRAdditions)- (NSDictionary *)dictionaryByReplacingNullsWithStrings { const NSMutableDictionary *replaced = [self mutableCopy]; const id nul = [NSNull null]; const NSString *blank = @""; for(NSString *key in self) { const id object = [self objectForKey:key]; if(object == nul) { //pointer comparison is way faster than -isKindOfClass: //since [NSNull null] is a singleton, they'll all point to the same //location in memory. [replaced setObject:blank forKey:key]; } } return [replaced copy];}@end
Usage:
NSDictionary *someDictThatHasNulls = ...;NSDictionary *replacedDict = [someDictThatHasNulls dictionaryByReplacingNullsWithStrings];
Rolling through the dictionary hunting for NSNull is one way to tackle the problem, but I took a slightly lazier approach. Instead of nil you could assign an empty string, but the principle is the same.
CPJSONDictionary.h
@interface NSDictionary (CPJSONDictionary)- (id)jsonObjectForKey:(id)aKey;@end
CPJSONDictionary.m
@implementation NSDictionary (CPJSONDictionary)- (id)jsonObjectForKey:(id)aKey { id object = [self objectForKey:aKey]; if ([object isKindOfClass:[NSNull class]]) { object = nil; } return object;}@end