The app side often needs to interact with the server, and JSON-formatted data is often used, and parsing json is often a thing to do.
Let's look at an example, in general, that's how we parse it:
//main.m//Demo#import<Foundation/Foundation.h>#import "Person.h"#import "Box.h"intMainintargcConst Char*argv[]) { /** * {* "name": "Mr.li", * "number": "007", * "box": {* "pen": "Hero", * "Phone": "iPhone" * "pad": "IPad Air" *} *}*/NSString*jsonstring =@"{"Name":"Mr.li", " Number":"007", "Box":{ "Pen":"Hero", "Phone":"IPhone Ten", "Pad":"IPad Air" } }";NSData*jsondata =[jsonstring datausingencoding:nsutf8stringencoding]; Nserror*error =Nil; Nsdictionary*jsondic = [Nsjsonserialization jsonobjectwithdata:jsondata options:nsjsonreadingmutablecontainers error:&ERROR]; person*person =[[Person alloc] init]; [Person setname:jsondic[@"name"]]; [Person setnumber:jsondic[@" Number"]]; Nsdictionary*boxdic = jsondic[@"Box"]; Box*box =[[Box alloc] init]; [Box setpen:boxdic[@"Pen"]]; [Box setphone:boxdic[@"Phone"]]; [Box setpad:boxdic[@"Pad"]]; Person.mybox=box; NSLog (@"%@", person); Retun0;?}
The person class (omit person.m, just rewrite the description method):
// Person.h// Demo#import <Foundation/Foundation.h>#import "Box.h"@interface** *mybox; @end
Box Class (Omit box.m, just rewrite the description method):
// Box.h// Demo#import <Foundation/Foundation.h>@interface * * *pad; @end
The key is that when the app side has a lot of data to interact with the server, such an analytic swan song is rather tired (pure physical activity).
As an ideal yard farmer, you have to think of a better way.
———— Secret:KVC ————
What is KVC? That is Key-value Coding. Simply put, a string key is passed to set the value of the key corresponding property.
To give a simple example:
[Person SetValue:@ "mr.zhang" forkey:@ "name"]; NSLog (@ "name:%@", Person.name); /* * * operation result: * Name:Mr.Zhang **
The principle of KVC is reflection, which is mapped by the string @ "name" and then modified.
Add Parsingdatafromdictionary in persion.m: Method
-(void) Parsingdatafromdictionary: (nsdictionary *) Parameters { for in Parameters) { id value = Parameters[key]; if NULL] && Value! = nil) { [self setvalue:parameters[key] forkey:key] ; Else { null] forkey:key];}} }
This can be problematic when the key is box, which causes the program to make an error.
There are two ways to solve this problem
Before solving, first implement Parsingdatafromdictionary in BOX.M: Method, (in fact, the method body exactly the same, here for the moment so write, later will be described can be packaged up), spare
The first type:
Modify Parsingdatafromdictionary: Method (bold word is new code),
for(NSString *keyinchparameters) { IDValue =Parameters[key]; Nserror *error = nil; if([self validatevalue:&value forkey:key error:&Error]) { if(Value! = [NSNullNULL] && Value! =Nil) {[self setvalue:parameters[key] forkey:key]; } Else{[Self setvalue:[nsnullNULL] Forkey:key]; } } }
Add Validatename: Error: Method in PERSON.M (name is the first letter of the <key>,key capital)
-(BOOL) Validatebox: (ID *) iovalue error: (nserror *__autoreleasing *) error { if Class]] { *box = [[Box alloc]initwithdictionary:*iovalue]; *iovalue = box; } return YES;}
<!!! Note: The ValidateName: Error: Method instead of overriding validateValue:forKey:error:!!! >
The second type:
In person.m, add Setvalue:forundefinedkey: Method,
-(void) SetValue: (ID) value forundefinedkey: (NSString *) key { NSLog (@ " Undefined key:%@, value:%@", Key,value); if ([Key isequaltostring:@ "box"class]]) { *box = [[Box alloc] initwithdictionary:value]; = box; }}
In all, the first option is to detect and revise before assigning values, and the second is to revise after the assignment fails.
The above two solutions can, seemingly the first kind of trouble, but for example when Person.box instance also called box, the second method is not solved, will lead to the box dictionary, forced assignment to Person.box, at this time the first solution is more convenient.
Parsing Json using KVC in IOS < a >