Storing [Nsnull Null] Values in Nsuserdefaults, from JSON Serialization, Causes Unwanted Exceptions

storing [NSNull null] values in NSUserDefaults, from JSON serialization, causes unwanted exceptions

I've tried some recursive solutions but they tend to be complicated and don't handle mixed type content well. At the simplest level here is a flat example that works well if you have a predictable, flat response to clean.

NSMutableDictionary *dictMutable = [dict mutableCopy];
[dictMutable removeObjectsForKeys:[dict allKeysForObject:[NSNull null]]];

TouchJSON, dealing with NSNull

nil and NULL are actually both equal to zero, so they are, in practice, interchangeable. But you're right, for consistency, the documentation for TouchJSON should have used theDeserializer.nullObject = nil instead of NULL.

Now, when you do that, your second predicate actually works fine:

if (![jsonDataDict objectForKey:someKey])

because TouchJSON omits the key from the dictionary when you have nullObject set to nil (or NULL). When the key doesn't exist in the dictionary, NSDictionary returns nil, which is zero so your if condition works as you expect.

If you don't specify nullObject as nil, you can instead check for null like so:

if ([jsonDataDict objectForKey:someKey] == [NSNull null])

Why is NSUserDefaults unwilling to save my NSDictionary?

Props to Kevin who suggested printing the values, of course one of which is of type NSNull which is not a property list value. Thanks!

The kludgy solution to my problem - iterate over the keys of the dictionary I just produced so conveniently with dictionaryWithValuesForKeys and remove those of type NSNull. sigh

NSMutableDictionary* dict = [NSMutableDictionary dictionaryWithDictionary:[self dictionaryWithValuesForKeys:keys]];
for( id key in [dict allKeys] )
{
if( [[dict valueForKey:key] isKindOfClass:[NSNull class]] )
{
// doesn't work - values that are entered will never be removed from NSUserDefaults
//[dict removeObjectForKey:key];
[dict setObject@"" forKey:key];
}
}

iOS, JSON-RPC and NSJSONSerialization: Dealing with null values

First of all {"telephone": "null"} is not a null value. There are quotes so actually telephone property has string value with text "null". Server needs to send {"telephone": null} - without quotes.
I'd go with listing all relevant properties that your app needs in response and put null as a value if there is not value. Then you can easily check in NSDictionary you get from NSJSONSerialization if value for key is NSNull.

if ([dictionaryValue isKindOfClass:[NSNull class]])
myThink.myProperty = nil;

NSMutableArray with [NSNull null] vs NSPointerArray

If you are putting objects in the NSMutableArray as well, say the chess pieces, stay with NSMutableArray. Also there is really no reason not to use [NSNull null], really not much different that putting a NULL in a NSPointerArray.

If you are concerned about performance measure before making any change.

Attempt to set a non-property-list object - NSUserDefaults

You can't have null in there.

property lists do not support explicit nulls

Wikipedia

Why can I return a NSMutableArray from NSUserDefaults but not an NSMutableDictionary

just because :D

copy the dictionary like this

NSMutableDictionary *d = [[NSUserDefaults standardUserDefaults] dictionaryForKey:@"bla"].mutableCopy;

Attempt to set a non-property-list object as an NSUserDefaults

The code you posted tries to save an array of custom objects to NSUserDefaults. You can't do that. Implementing the NSCoding methods doesn't help. You can only store things like NSArray, NSDictionary, NSString, NSData, NSNumber, and NSDate in NSUserDefaults.

You need to convert the object to NSData (like you have in some of the code) and store that NSData in NSUserDefaults. You can even store an NSArray of NSData if you need to.

When you read back the array you need to unarchive the NSData to get back your BC_Person objects.

Perhaps you want this:

- (void)savePersonArrayData:(BC_Person *)personObject {
[mutableDataArray addObject:personObject];

NSMutableArray *archiveArray = [NSMutableArray arrayWithCapacity:mutableDataArray.count];
for (BC_Person *personObject in mutableDataArray) {
NSData *personEncodedObject = [NSKeyedArchiver archivedDataWithRootObject:personObject];
[archiveArray addObject:personEncodedObject];
}

NSUserDefaults *userData = [NSUserDefaults standardUserDefaults];
[userData setObject:archiveArray forKey:@"personDataArray"];
}


Related Topics



Leave a reply



Submit