Cocoa: json string deserialization for custom objects (not NSDictionary, NSArray)

There are several useful libraries in java-land that convert json strings to matching type objects. The json libraries I've seen for cocoa just create nested NSDictionaries and NSArrays. Is there a tool out there that will go the extra step of restoring any type of object I want?

So, for example, if I have a class called "Unicorn" with the "maneColor" property, and I have json that looks like this:

{ "maneColor":"silver" } 

I can automatically instantiate a Unicorn object with "maneColor" set to "silver".

+7
source share
4 answers

I don’t know of any specific implementations, but the key value of coding is very close to you: Guide to coding key values . I had good results combining streaming json parsing with KVC.

The -setValue: forKey: method makes it much easier to adapt serialized data to user objects. To continue your example, you must create a Unicorn class with all the necessary access methods: -setName: / - name, -setManeColor / -maneColor, etc. (You may be able to use properties for some expected values, but for example, with the value maneColor, where you probably want to write a custom setter to convert from a color name string to an NSColor or UIColor object.)

You will also want to add two more methods to your custom object: -setValue: forUndefinedKey: and -valueForUndefinedKey :. These are methods that will be called if your object does not have access methods that correspond to the key passed to the KVC methods. Here you can get unexpected or unsupported values ​​and store them or ignore them as needed.

When you send -setValue: forKey: to a Unicorn object, the structure looks for accessors matching the key pattern. For example, if the key is "maneColor" and you set the value, the environment checks if your object implements -setManeColor :. If so, it calls this method, passing the value; otherwise, -setValue: forUndefinedKey: is called, and if your object does not implement it, an exception is thrown.

When your parser delegate is notified of the start of parsing the json unicorn object, create an instance of the Unicorn object. When your parser returns the parsed data to you, use -setValue: forKey: to add data to your object:

 - ( void )parserDidBeginParsingDictionary: (SomeParser *)p { self.currentUnicorn = [ Unicorn unicorn ]; } - ( void )parser: (SomeParser *)p didParseString: (NSString *)string forKey: (NSString *)key { [ self.currentUnicorn setValue: string forKey: key ] } - ( void )parserDidFinishParsingDictionary: (SomeParser *)p { [ self.unicorns addObject: self.currentUnicorn ]; } 
+7
source

Use Jastor - https://github.com/elado/jastor Already parses JSON into an NSDictionary and populates an instance of the real Objective-C class.

 NSDictionary *parsedJSON = (yajl, JSONKit etc) Unicorn *unicorn = [[Unicorn alloc] initWithDictionary:parsedJSON]; unicorn.maneColor // "silver" 
+7
source

As any subclass of NSObject conforms to the NSKeyValueCoding protocol:

 NSDictionary *parsedJSON = //whatever id <NSKeyValueCoding> entity = [[CustomNSObjectSubclass alloc] init]; [entity setValuesForKeysWithDictionary:parsedJSON]; 
+1
source

Apple has added the NSJSONSerialization class to iOS 5.0, which, according to the documentation , does the following:

You use the NSJSONSerialization class to convert JSON to Foundation objects and convert Foundation objects to JSON.

An object that can be converted to JSON must have the following Properties:

The top-level object is NSArray or NSDictionary. All objects are instances of NSString, NSNumber, NSArray, NSDictionary, or NSNull. All dictionary keys are instances of NSString. The numbers are not NaN or infinity.

Here's a tutorial and a wrapper method so you can start.

0
source

All Articles