NSDictionaray dictionaryWithObjectsAndKeys adding NULL value
Creating NSDictionary objects can be combersome if you have many objects, that if they are nil, should not be included in the dictionary.
To me NSNull is as big a problem as it is the solution. When creating NSDictionary objects for usage in other objects, you can go two ways when dealing with nil values. Either you add NSNull objects to your dictionary - and then check for NSNull values when reading the values. This makes pretty code at the point of creation, but it becomes messy when reading out the values. Ex. should you check all keys in the dictionary, or are some garanteed to be not nil? And if an NSNull value is not filtered out it is bound to make exceptions when trying to send the object messages.
The second way is to just not add NSNull values to the dictionary. This is convinient when reading the NSDictionary, as the [someDictionary objectForKey:someKey] simply returns nil when the key is not set. This approach makes it pretty this easy when reading the values, but it really is bound to be messy code on creation. Ex. Creating a NSMutableDictionary, checking for nil before adding values, and finally returning an immutable copy?
Solution
To me the solution has been to create two categories, which in essense makes it easy for both the creating and the reading ends.
When creating the NSDictionary, you simply wrap you possible-nil values like this
[NSDictionary dictionaryWithObjectsAndKeysIngoringNull:
[NSNull nullWhenNil:val1], @"value1",
[NSNull nullWhenNil:val2], @"value2",
...
nil];
This code is almost as simple as approach number one, but it makes it substantially easier when reading out the values.
The categories is as follows (works in both ARC enabled and non-ARC code):
NSDictionary addition:
@implementation NSDictionary (NullAddition)
+ (id)dictionaryWithObjectsAndKeysIngnoringNull:(id)firstObject, ... {
NSMutableArray* objects = [NSMutableArray array];
NSMutableArray* keys = [NSMutableArray array];
va_list args;
va_start(args, firstObject);
for (id object = firstObject; object; object = va_arg(args, id)) {
id key = va_arg(args, id);
if (!key)
break;
if (![object isKindOfClass:[NSNull class]]) {
[objects addObject:object];
[keys addObject:key];
}
}
va_end(args);
return [self dictionaryWithObjects:objects forKeys:keys];
}
@end
NSNull addition
@implementation NSNull (NullAddition)
+ (id)nullWhenNil:(id)obj {
return (obj ? obj : [self null]);
}
@end
Good luck!
You need to check if the string is null. If it is, add [NSNull null]
instead of your string.