This article transferred from: http://blog.csdn.net/smking/article/details/40432287
Let's talk about how to use Jsonmodel.
@inteface Mymodel:jsonmodel
1. When using Jsonmodel, there is no need to check if the desired server properties are returned. Jsonmodel's Initwithdictionary method is automatically checked and processed.
2. Validity check, if a field returned by the specified server is not returned and is required, as in the following case, an exception is thrown.
This property is required
@property (Strong, nonatomic) nsstring* string;
Because this value is required by default.
In general, we do not want to cause the program to crash because some value of the server does not return, we add the keyword optional.
This one ' s optional
@property (Strong, nonatomic) nsnumber<optional>* number;
3. Atomic data, which might have been done before
if (jsondict[@ "name"])
labelName.Text = jsondict[@ "name"];
Else
[Self showerrormessageandbailout];
This code causes the jsondict[@ "name" to be read, then valid, and finally used. In other words, this is used three times, and if in some cases, it has been wrong to use it once, it is not possible to prevent it from following successive errors.
If you use the Jsonmodel property, you will only be guaranteed to use it once, and you can judge the validity and use it. (In fact, it can be done, just take this value out, save it and then use it, but the code will be a bit cumbersome)
Read a batch of data at the same time as the following code:
The simple model is as follows:
simplemodel* model = [[Simplemodel alloc] initwithstring:@ "... json here ..." error:nil];
The complex model is as follows, where a complex model is assumed to contain a simple model. The main purpose is to explain the model before the inclusion of the case, can still be resolved.
supercomplicatedmodel* model = [[Supercomplicatedmodel alloc] initwithstring:@ "... json here ..." error:nil];
Batch of models, that is, one batch of models can be processed at a time.
nsarray* models = [Supercomplicatedmodel arrayofobjectsfromdictionaries:jsondatas error:nil];
4. Data conversion, OC <-> JSON
Note the following picture: This means that the JSON data format is only the middle part, String,number, array, object, and Null
For example, the JSON data is as follows:
{
"First": 1,
"Second": 35,
"Third": 10034,
"Fourth": 10000
}
This model can be defined as follows
@interface Numbersmodel:jsonmodel
@property (assign,nonatomic) short first;
@property (assign,nonatomic) double second;
@property (strong,nonatomic) nsnumber* third;
@property (strong,nonatomic) nsstring* fourth;
@end
Note: In JSON data, first is 1,second 35, but they can be automatically converted to short, double type. For 10034, and 10000 are automatically converted to NSNumber and NSString. These are the jsonmodel that will be done automatically. It's amazing!
5. Embedded data conversion, in the Jsonvaluetransformer class, there are various embedded conversion support. As below
{
"Purchasedate": "2012-11-26t10:00:01+02:00",
"Blogurl": "Http://www.touch-code-magazine.com"
}
is a date type, and a URL type, respectively.
@interface Smartmodel:jsonmodel
@property (Strong, nonatomic) nsdate* purchasedate;
@property (Strong, nonatomic) nsurl* Blogurl;
@end
With the above model, no additional code is required, i.e. the desired conversion can be obtained.
The following conversions are supported in this Jsonvaluetransformer class
Nsmutablestring <-> NSString
Nsmutablearray <-> Nsarray
NS (Mutable) Array <-Jsonmodelarray
Nsmutabledictionary <-> Nsdictionary
Nsset <-> Nsarray
BOOL <-> number/string
String <-> number
String <-> URL
String <-> time zone
String <-> Date
Number <-> Date
6. Custom data conversion, it is obvious that the above inline conversion is sometimes not enough to meet our needs, so we need the following custom conversion.
All you need to do is customize a jsonvaluetransformer category file, as follows:
@interface Jsonvaluetransformer (Uicolor)
-(uicolor*) uicolorfromnsstring: (nsstring*) string;
-(ID) Jsonobjectfromuicolor: (uicolor*) color;
@end
And then implement them.
Note that the above naming is used:
-(yourpropertyclass*) Yourpropertyclassfromjsonobjectclass: (jsonobjectclass*) name;
For example:
-(uicolor*) uicolorfromnsstring: (nsstring*) string;
To convert this type to JSON, like this: (note the following ID, can be modified or not modified to nsstring, because it must know that this is a nsstirng. Heqin: It could actually be something else, and it should be a specific judgment based on a particular situation. )
-(ID) Jsonobjectfromyourpropertyclass: (yourpropertyclass*) color;
Here is another example:
@implementation Jsonvaluetransformer (Customtransformer)
-(NSDate *) nsdatefromnsstring: (nsstring*) string {
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[Formatter Setdateformat:apidateformat];
return [formatter datefromstring:string];
}
-(NSString *) Jsonobjectfromnsdate: (NSDate *) Date {
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[Formatter Setdateformat:apidateformat];
return [formatter stringfromdate:date];
}
@end
7. Nesting levels.
{
"Idimage": 1,
"Name": "House.jpg",
"Copyright": {"author": "Marin Todorov", "Year": 2012}
}
You can define the following models first
@interface Copymodel:jsonmodel
@property (Strong, nonatomic) nsstring* author;
@property (assign, nonatomic) int year;
@end
Then define the model:
#import "CopyModel.h"
@interface Imagemodel:jsonmodel
@property (assign, nonatomic) int idimage;
@property (Strong, nonatomic) nsstring* name;
@property (Strong, nonatomic) copymodel* copyright;
@end
Then after you get the Imagemodel, you will find that the Copymodel also have data.
If you want an array of model properties, as follows.
@property (Strong, nonatomic) nsarray<tweetmodel>* tweets;
8. Jsonmodel converted to Dictioanry, jsonstring.
Direct use of Jsonmodel method Todictioanry, and tojsonstring can be.
9. Save Model data
nsdictionary* object = [Nsdictionary Dictionarywithcontentsoffile:filepath];
data = [[Mydatamodel alloc] initwithdictionary:object];
Save operation
[[Data ToDictionary] Writetofile:filepath Atomically:yes];
Key mapping, sometimes, the data obtained is not at one level, as follows:
{
"order_id": 104,
"Order_Details": [
{
"Name": "Product#1",
"Price": {
"USD": 12.95
}
}
]
}
The order_id and name are not a hierarchy, but we still want to get their data in a model. As follows:
@interface Ordermodel:jsonmodel
@property (assign, nonatomic) int id;
@property (assign, nonatomic) float price;
@property (Strong, nonatomic) nsstring* productName;
@end
@implementation Ordermodel
+ (jsonkeymapper*) keymapper
{
return [[Jsonkeymapper alloc] initwithdictionary:@{
@ "order_id": @ "id",
@ "Order_details.name": @ "ProductName",
@ "ORDER_DETAILS.PRICE.USD": @ "price"//here takes the KVC way to take the value, it assigns the price property
}];
}
@end
11. Global key Mapping. (Make all models available), personally think this is not very common, because if really need all models have this keymapper conversion, then directly inherit a base class on the line.
[Jsonmodel setglobalkeymapper:[
[Jsonkeymapper Alloc] initwithdictionary:@{
@ "item_id": @ "id",
@ "Item.name": @ "ItemName"
}]
];
12. Automatically name the underline style to the hump named property. There are similar ways to convert uppercase to lowercase: mapperfromuppercasetolowercase
{
"order_id": 104,
"Order_product": @ "Product#1",
"Order_price": 12.95
}
The resulting model
@interface Ordermodel:jsonmodel
@property (assign, nonatomic) int orderId;
@property (assign, nonatomic) float orderprice;
@property (Strong, nonatomic) nsstring* orderproduct;
@end
@implementation Ordermodel
+ (jsonkeymapper*) keymapper
{
return [Jsonkeymapper mapperfromunderscorecasetocamelcase];
}
@end
13. Optional attributes, it is recommended to use this method as far as possible to avoid exceptions.
{
"id": "123",
' name ': null,
"Price": 12.95
}
The resulting model is as follows:
@interface Productmodel:jsonmodel
@property (assign, nonatomic) int id;
@property (Strong, nonatomic) nsstring<optional>* name;
@property (assign, nonatomic) float price;
@property (Strong, nonatomic) nsnumber<optional>* uuid;
@end
@implementation ProductModel
@end
With the above optional, we can add a issuccess method to this class that determines whether the name and UUID exist to determine whether the data is successfully taken from the server. Instead of setting these two properties to required, you can effectively avoid exceptions.
The Ignore property makes parsing completely ignore it. In general, the ignored attribute is primarily used when the value is not fetched from the server, but is set by the following code.
{
"id": "123",
' Name ': null
}
The model is:
@interface Productmodel:jsonmodel
@property (assign, nonatomic) int id;
@property (Strong, nonatomic) nsstring<ignore>* CustomProperty;
@end
@implementation ProductModel
@end
You can use the following method, so that all the properties of the current class are optional, the official network said to avoid such use, (I think that the official website means, as far as possible to avoid using the surface method to specify all the attributes are optional, even if all the properties are optional, also try to mark each attribute there as optional)
@implementation ProductModel
+ (BOOL) propertyisoptional: (nsstring*) PropertyName
{
return YES;
}
@end
15. Lazy loading, this comparison is recommended, can reduce the performance consumption when read on the network: The keyword is: convertondemand
{
"order_id": 104,
"Total_price": 103.45,
"Products": [
{
"id": "123",
"Name": "Product #1",
"Price": 12.95
},
{
"id": "137",
"Name": "Product #2",
"Price": 82.95
}
]
}
Using the Model:
@protocol ProductModel
@end
@interface Productmodel:jsonmodel
@property (assign, nonatomic) int id;
@property (Strong, nonatomic) nsstring* name;
@property (assign, nonatomic) float price;
@end
@implementation ProductModel
@end
@interface Ordermodel:jsonmodel
@property (assign, nonatomic) int order_id;
@property (assign, nonatomic) float Total_price;
@property (Strong, Nonatomic) Nsarray<productmodel, convertondemand>* products;
@end
@implementation Ordermodel
@end
16. Use Jsonhttpclient for requests.
Add extra headers
[[Jsonhttpclient Requestheaders] setvalue:@ "MySecret" forkey:@ "Authorizationtoken"];
Make post, GET requests
[Jsonhttpclient postjsonfromurlwithstring:@ "Http://mydomain.com/api"
params:@{@ "postParam1": @ "value1"}
completion:^ (ID json, Jsonmodelerror *err) {
Check err, Process json ...
}];
Well, so the use of Jsonmodel has been here, integrated the use of the official website method.
The JSON model for iOS