On most of the apps I develop, I usually have my own foundation classes, MKViewController, MKButton, MKLabel, MKThis and MKThat. One of the most often used/abused class is the MKObject class. This is the burial ground for methods that don’t fit elsewhere.

MKObject is a subclass of NSObject that adds convenient methods that I believe should be provided by Apple themselves.

I wrote some methods, categories on MKObject that would allow you to serialize any MKObject as JSON (using iOS 5 NSJSONSerialization) or XML (using KissXML). Of late, I have been playing with Parse, the backend as a service and wrote a category addition to this MKObject that would convert any MKObject derived subclass into a PFObject.

When I say, any MKObject derived subclass, don’t fret. You can easily convert an NSObject derived subclass in your project to an MKObject derived subclass without losing features/functionality since MKObject itself is a subclass of NSObject.

Features

So why do you need this MKObject? Let’s consider that you have a model called “User” and “Friend” (both a kind of “MKObject”)

Parse

A user has a list of friends. The traditional way to add a new friend to a user and saving it to Parse would be

PFObject *object = [PFObject objectWithClassName:@"User"];
NSMutableArray *friends = [object objectForKey:@"friends"];
[friends addObject:newFriend];
[object setObject:friends forKey:@"friends"];
[object saveInBackground];

Alternatively, if your User and Friend objects were MKObject subclasses, the above code would be as simple as,

[user addFriend:newFriend];
[[user pfObject] saveInBackground];

The category method, pfObject converts any MKObject subclass to a PFObject that can be saved to Parse easily. You don’t have to mess around with dictionaries and arrays manually. It just works.

XML

Hold on, MKObject is even more powerful than you think. It can convert any object to an equivalent XML tree. What more? MKFoundation is super lean that if you don’t use XML in your application, you don’t have to add the XML category extension classes. The foundation library is designed to avoid bloats in your code.

The classes MKObject+XMLExtentions.h/m provide XML support. It depends on the KissXML library to build the XML tree from your object.

JSON

We are not done yet. How good is a foundation object if it can do XML but not JSON? Does anyone even use XML/SOAP these days? Fret not. MKObject supports built in JSON serialization as well.

The method

[user prettyJSONString]

will convert the complete user object to a JSON string pretty printed for display.

Similarly, the method

[user jsonString]

will convert the complete user object to a JSON string ready to be sent to your server or serialized.

Deserialization

To complete the circle, MKObject also provides convenience methods to deserialize JSON/XML or Parse’s PFObjects back to MKObject objects.

When converting from JSON, call

[[MKObject alloc] initWithJSONString:string];

When converting from XML, call

[[MKObject alloc] initWithXMLString:string];

When converting from a PFObject, call

[MKObject objectFromPFObject:object];

Why should you use MKObject?

Ok, all fine, but why should I convert a JSON string to an object. Why can’t I pass the JSON strings to the view controllers?
The advantage of using a model class is clarity and ability to catch errors at compile time. For example, accessing
[userDictionary objectForKey:@”first_name”] instead of [userDictionary objectForKey:@”firstName”] will fail at run time. But

Accessing user.first_name instead of user.firstName will fail at compile time. Fail early, fail often

If you are using MKNetworkKit, using an MKObject subclass will help you write cleaner code without messing around with raw JSONs. The below code snippet explains this.

 [op onCompletion:^(MKNetworkOperation *completedOperation) {
 
    NSMutableArray *foodList = [NSMutableArray array];
 
	MKUser *user = [[MKUser alloc] initWithJSONString:[completedOperation responseJSON]];
    succeededBlock(user);
  } onError:^(NSError *error) {
 
    DLog(@"%@", error);
  }];

Requirements

MKObject is lean enough that you just have to add the necessary files into your project depending on what serialization support you need.

For JSON support, just copy MKObject.h/m files to your project. Change all your NSObject based models to MKObject based models.

For XML support, just copy MKObject.h/m and MKObject+XMLExtenstions.h/m files to your project. Change all your NSObject based models to MKObject based models. Add KissXML framework to your project. To add KissXML to your project, follow the getting started page here

XML deserialization is slightly tricky. You should add “known deserializers” by calling

[MKObject registerKnownClass:[Friend class]];

For Parse support, copy MKObject.h/m and MKObject+ParseExtensions.h/m files to your project. Change all your NSObject based models to MKObject based models.

Start saving your models to parse by calling

[[myObject pfObject] saveInBackground]

Source code

Complete source code is available royalty free on Github. Feel free to fork or use it in your apps. It’s licensed under a very liberal GPL (pun) MIT license. :)

MKFoundation on Github


Mugunth

Follow me on Twitter