Monday, June 24, 2013

NSJSONSerialization Junk in the Trunk

As a mobile developer, I have come to embrace (but not love) the Objective-C language for developing purely-native iOS applications. Having not touched C/C++ since I was in college, it has already been a bumpy road to get reacquainted with semantics, structures, etc. As an aside, I think it is this barrier to entry that keeps so many people (myself included) interested in frameworks like PhoneGap/Cordova as a bridge to semi-native development. That, however, is an entirely different subject.

On the road to learning how to "code for Apple," I noted a few things:
  • Documentation is there, but learning to read the documentation is an additional skill one must master before you hope to get too much from what is out there
  • Sites like StackOverflow are essential to learning from those who have blazed these difficult trails before you
  • The best way to learn is by messing it up a couple hundred times; the failures are good reference points for when you need to do other things
Even now, after I have picked up steam in development on this platform, I still run into strange things that I am unaccustomed to in other areas of development. Specifically, in translating to and from JSON for communicating with a .NET web service.

The Problem
I kept noticing that serialization of dictionary objects to JSON would randomly produce "junk" characters at the end. The dictionaries would range in number of elements and depth (some would be a dictionary wrapped in a dictionary). Upon closer inspection, I even noted that pieces of the correctly-serialized JSON key/value pairs would be copied incompletely to the end of the well-formatted object, thus creating an invalid JSON object.

For example:
{ "Name" : "one", "Numeral" : 1}

Might become:
{ "Name" : "one", "Numeral" : 1}eral" : 1}

Of course, when it came time to turn this JSON back into a type object, the parser would get rather angry.

The Solution
After doing some searching I noticed that you could pass a special option to NSJSONSerialization that was intended to notify it that you were using a mutable dictionary. That got me to thinking: what if the problem stemmed from using mutable objects? So, just before serializing I copied the mutable object into an immutable one and used the product of that operation to feed the serializer. And it worked.

Here is the sample code that I use to do this (just for reference):
- (void)syncGenericUpdate :(NSString *)URL :(NSMutableDictionary *)Record {
    NSURL *url = [[NSURL alloc] initWithString:URL];
    NSDictionary *params = [[NSDictionary alloc] initWithDictionary:Record];
    NSError* error;

    NSData *json = [NSJSONSerialization dataWithJSONObject:params options:NSJSONReadingMutableContainers & NSJSONWritingPrettyPrinted error:&error];

I have left the NSJSONReadingMutableContainers option in as you can see, but only for superstitious reasons. Hope this helps someone who is trying to figure out how to stop the junk characters in their JSON.

No comments:

Voice Comments