Jsonmodel is a data model framework for IOS and OSX. It ' s written in Objective-c and helps you several different ways. You can read more on its key features below:
- Rapidly write model code
- Validation of the model ' s input
- Atomic data
- Type casting between JSON and Obj-c
- Built-in data Transformers
- Custom Data Transformers
- Model cascading
- Convert Back & Forth From/to JSON
- Persist model State in memory or file
- Create models straight from the Internet
- Automatic Model Compare methods
Features:1. Rapidly write model Codeif you has written IOS apps, which fetch and work with JSON from the web, you probably has Writt En tons of this kind of code:
Self.id = [jsondict objectforkey:@ "id"];self.name = [jsondict objectforkey:@ "name"];self.profileimagebig = [jsonDict objectforkey:@ "Profile_image_big"];self.profileimagesmall = [jsondict objectforkey:@ "Profile_image_small"]; Self.profileimagesquare = [jsondict objectforkey:@ "profile_image_square"];self.firstname = [jsonDict objectForKey:@] FirstName "];self.familyname = [jsondict objectforkey:@" familyname "];self.age = [jsondict objectforkey:@" age "];
What sucks on this code is so you first need the declare all you have properties in your interface file and then go ahead a nd write Init method for your model, just reads the JSON through and copy all of the values over to your propertis.
That's a lot of manual labor! But Hey-it's the future now!
Jsonmodel removes the need to write initializer code to your models.
Just declare properties in your model with the same names as the keys in your JSON and voila! The heavy work was done automatically for you.
So, just declare your properties like usual in your interface file:
@interface Mymodel:jsonmodel@property (Strong, nonatomic) nsstring* ID; @property (strong, nonatomic) nsstring* name; etc ...) @end
Jsonmodel ' s inherited Initwithdictionary:method would take care of match incoming JSON keys with your model ' s properties, and copy over the matching ones. No need of any code in your implementation file. 2. Validation of the model ' s inputdoes *this* code look familiar?
Self.profileurl = [jsondict objectforkey:@ "Profileurl"]; //todo:what to does if there ' s no URL in the JSON? Should we handle this somehow? if (!self.profileurl) NSLog (@ "Something ' s broken with the JSON API");
When you write a model the traditional-A, you also need to validate whether the keys your model need is found in the Coming JSON.
However, that's not always what's happening (partially due to the traditional a-handling in errors, I Cocoa ' t Blame anybody for skipping in that).
Problem is-in the end you either write all the code to check whether the JSON keys exist, or your leave your app to free Fall when there ' s a problem.
If your models inherit Jsonmodel, there ' no need for extra code to check whether the required JSON structure are in place. Jsonmodel ' s Initwithdictionary:method checks that automatically.
All properties your define in your model would be required. If They is not present in the input, you'll get an exception.
However you can also define some of the properties as not-required, and so ' s also very easy:
//this property is required @property (Strong, nonatomic) nsstring* string; //this One ' s optional @property (Strong, nonatomic) nsnumber<optional>* number;
3. Atomic datahaving A good model guarantees you don't have half-baked User Interface or mysterious crashes. What am I talking about? Consider this code (that probably a colleague of yours wrote, it is not your for sure):
if (jsondict[@ "name"]) labelName.Text = jsondict[@ "name"];else [self showerrormessageandbailout]; if ( jsondict[@ "Age"]) Labelage.text = jsondict[@ ' age '];else [self showerrormessageandbailout];
Do you notice the problem? The code reads and validates and data, and in the same time updates the user interface.
So, when an error occurs there's no to rollback the already applied changes.
Jsonmodel does all data reading and validation atomically. You call one method, which either succeeds or fails and then you can use the data being sure it ' s valid and alright.
Here's how to make a instance of your data model when it contains just few strings and numbers:
simplemodel* model = [[Simplemodel alloc] initwithstring:@ "... json here ..." error:nil];
And here's how do you do a instance of model, which contains other models, and have JSON data converted to custom classes W Hen read:
supercomplicatedmodel* model = [[Supercomplicatedmodel alloc] initwithstring:@ "... json here ..." error:nil];
And here are how you read a list of models, as each of the them is the described above model:
nsarray* models = [Supercomplicatedmodel arrayofobjectsfromdictionaries:jsondatas error:nil];
As you see-instantiation are always one-liner, which you can comfortably error handle. 4. Type casting between JSON and Obj-cjson are awesome but the problem with it are that both your backend (PHP, Ruby, C #, WH At has you) and your app (OBJECTIVE-C) has a rich types range, but the JSON does not. To put things visually here's what's happens when you consume a JSON feeds from the Web:
If you catch my drift-the JSON format is a incredible data type bottleneck in between your apps and your server back end . While Jsonmodel lives-on IOS it cannot does much about the "right" side of json-the communication to your server .
What it can do are to help you cast the JSON data to Objective-c types!
Just Define your properties ' types as the types you ' d like to has and Jsonmodel would try to convert the incoming data to Satisfy your needs.
There is a look in this JSON feed:
{ "First": 1, "second": +, "third": 10034, "fourth": 10000}
You have four keys and their values is numbers, therefore you get the same old NSNumber back when you parse the JSON your Self.
Not with Jsonmodel you don ' t! You just specify the types of your properties and Jsonmodel then converts the data for you, like so:
@interface Numbersmodel:jsonmodel @property (Assign, nonatomic) short first; @property (assign, nonatomic) double second; @property (Strong, nonatomic) nsnumber* third; @property (strong, Nonatomic) nsstring* fourth; @end
Again-no implementation code needed for this to work! 5. Built-in data Transformersjsonmodel comes with built-in value transformers, declared in a separate class called Jsonval Uetransformer. It handles basic value conversions between the most common class types, that's you might use in a JSON feed.
The built-in transformers work behind the scene, so you ' d never even has to know they kick in and do the heavy lifting fo R you.
For example you might has this JSON:
{ "purchasedate": "2012-11-26t10:00:01+02:00", "Blogurl": "Http://www.touch-code-magazine.com"}
This JSON includes a date in the format (widely used in JSON APIs) and it comes to your IOS app as a string, because JSON Does not has a data type "date".
The second element in the JSON code is a URL; Again it comes to the plain string, since JSON does not has a URL data type.
To make use of the built-in transformers, just create your model as:
@interface Smartmodel:jsonmodel @property (Strong, nonatomic) nsdate* purchasedate; @property (Strong, nonatomic) nsurl* Blogurl; @end
Jsonmodel see that there's a mismatch between the incoming types and your model ' s properties types, and that's when the Tran Sformers kick in and convert the values. The end you just use your properties as normal. Smooth. 6. Custom Data Transformersof Course not every value can is automatically converted to any other value. That's where you're on board.
You can add transformers to Jsonvaluetransformer for your own project.
You need the new category on Jsonvaluetransformer and add the methods to the this category. That's all. Like so:
@interface Jsonvaluetransformer (Uicolor)-(uicolor*) uicolorfromnsstring: (nsstring*) string;-(ID) Jsonobjectfromuicolor: (uicolor*) color; @end
This example adds transformer for a uicolor* property, which gets it value from a HEX encoded color coming in as a string . The first method you declare are named like so:
-(yourpropertyclass*) Yourpropertyclassfromjsonobjectclass: (jsonobjectclass*) name;
Therefore since the HEX color comes from JSON as a nsstring, and your property is of type uicolor* your method name Shoul D be:
-(uicolor*) uicolorfromnsstring: (nsstring*) string;
It makes sense? It ' s easy? Yes-i agree.
The second method is need for exporting your model to JSON (if you need to do). The It works in the same-in-the-same-the-doesn ' t imply is the exported JSON object data type. It ' s up to decide.
Check the included jsonvaluetransformer+uicolor.h/m files for a full example how to write custom transformers. 7. Model Cascadingif You is working with a pretty complicated APIs, you'll definitely need to has models, which contain Other models.
Let me show you a example of an image, which beside simple properties, also contains a copyright, which is a model itself .
Here's the JSON you get:
{ "idimage": 1, "name": "House.jpg", "Copyright": {"author": "Marin Todorov", "Year": 2012}}
It's pretty simple-to-define your models for the this JSON. Just has first your copyright model defined:
@interface Copymodel:jsonmodel @property (Strong, nonatomic) nsstring* author; @property (assign, nonatomic) int year; @end
And then define your Image model, which contains the copyright model, such as:
#import "CopyModel.h" @interface Imagemodel:jsonmodel @property (assign, nonatomic) int idimage; @property (Strong, nonatomic) nsstring* name; @property (Strong, nonatomic) copymodel* copyright; @end
That ' s it. When you initialize an instance of the Imagemodel, it'll see that one of the properties is a jsonmodel itself, and would Parse properly the JSON input.
boom!
How on when do you have a single model as a property, but a list of models for example?
Well JSON lists come through as Nsarray objects, you just has to also specify which model you expect in the list:
@property (Strong, nonatomic) nsarray<tweetmodel>* tweets;
Also need to add a protocol definition to your model interface file, and the protocol name should Match your model name. So-a model called Tweetmodel (as in the example above), add in TweetModel.h:
@protocol Tweetmodel @end
That ' s it. Now your top Model can cascade inside the JSON structure and read through multilevel structures.8. Convert Back & Forth from/to Jsona great model converts back to the format it is loaded from. Therefore Jsonmodel features a default
todictionarymethod, and another one called
tojsonstring.
You can then easily turn your model to a JSON compliant object at any time by calling ToDictionary on your model ' s INSTANC E.
Or you can just get the text representation of your current model data by calling toJSONString.
Pretty handy if you need to send the modified model back through the network to your server! 9. Persist model data in memory or Fileand finally you can use Jsonmodel as a easy-to-use-to-store files on your device ' s di Sc. Since data typing and converting to JSON compliant types are already handled for your, you just need to call a single method To save to the disc.
Loading model form the disc:
//load from File nsdictionary* object = [Nsdictionary Dictionarywithcontentsoffile:filepath]; //initialize model with data data = [[Mydatamodel alloc] initwithdictionary:object];
and saving it back to the disc:
//save to Disc [[Data todictionary] Writetofile:filepath Atomically:yes];
Create models straight from the Internetdocs coming in soon ... Automatic model Compare Methodsdocs coming in soon ...
Jsonmodel the use of a detailed