RestKit使用RKClient方式处理JSON数据
使用RestKit方式处理JSON数据有两种方式,一种是ObjectManager方式,另一种是RKClient方式,前段时间一种使用RestKit文档中推荐使用的ObjectManager方式即JSON本地映射的方式去处理数据,但是最近在处理一个有着三层字段嵌套的JSON数据时,发现这样的本地映射相当复杂,所以改用RKClient方式进行数据的请求。RKClient方式使用get方式获得从服务器请求来的完整JSON字符串后,我们还不能按照字段名称的方式使用这些数据,所以我们需要使用SBJson库来自动解析JSON字符串。SBJson有独立的库,不过好在RestKit库中已经包含了SBJson,所以我们在使用SBJson进行JSON数据解析的时候只需要添加如下头文件:
#import <RestKit/Support/JSON/SBJSON/JSON.h>
当然我们仍然需要RestKit标准头文件:
#import <RestKit/RestKit.h>
#import <RestKit/CoreData/CoreData.h>
RKClient方式步骤
步骤一:初始化
RKClient *client = [RKClient clientWithBaseURL:@"http://10.108.14.2"];
[[RKClient sharedClient]setValue:@"application/json" forHTTPHeaderField:@"Accept"];
初始化在应用程序初始化函数中添加。初始化的第一句指定了要请求的服务器基地址,第二句指定要访问的数据类型为JSON,如果没有第二句那么请求的数据格式则为text/html。
步骤二:JSON数据请求
假设我们从服务器将要获得的JSON数据格式如下:
{
"prodId":"00001",
"name":"苹果iphone4"
"adSlogan":"新一代苹果,超低价格",
"price":1888.00,
"storage":30,
"prodImg":[{"imgPosSerNum":1,"path":"/images/retail_brief_p1.jpg"},
{"imgPosSerNum":2,"path":"/images/retail_brief_p2.jpg"},
{"imgPosSerNum":3,"path":"/images/retail_brief_p1.jpg"}],
"prodDetailDesc":null,
"prodSpecsPropTemplateInfo":
[{
"prodPropId":"100329",
"prodPropName":"颜色",
"prodExtendSpecsPropInfo":
[{"prodPropPresValueStorage":"10","prodPropValue":"白色","prodPropPresValue":"","prodPropValueId":"10032901"}, {"prodPropPresValueStorage":"20","prodPropValue":"黑色","prodPropPresValue":"","prodPropValueId":"10032902"}]}, {
"prodPropId":"100330",
"prodPropName":"容量",
"prodExtendSpecsPropInfo":
[{"prodPropPresValueStorage":"10","prodPropValue":"16G","prodPropPresValue":"","prodPropValueId":"10033001"}
{"prodPropPresValueStorage":"20","prodPropValue":"32G","prodPropPresValue":"","prodPropValueId":"10033002"}]}],
}
添加:
-(void)viewDidAppear:(BOOL)animated
{
[[RKClient sharedClient]get:@"/shopping/retail/brief/1001" delegate:self];
}
使用RKClient方式进行数据请求最大的好处就是不需要进行很复杂的类映射,所以在初始化完毕之后我们便可以进行数据的请求了。代码中get指定请求的方式为GET方式,URL指定了相对服务器基地址的相对地址。
步骤三:请求回调
在数据请求完毕之后我们需要实现回调函数来获取请求获得的JSON格式数据。首先需要在当前试图控制器的.h文件中实现协议<RKRequestDelegate>,然后在.m文件中添加如下回调函数:
-(void)request:(RKRequest *)request didLoadResponse:(RKResponse *)response
{
if([request isGET])
{
if([response isOK])
{
SBJsonParser *parser = [[SBJsonParser alloc]init];
NSString *jsonstring = [response bodyAsString];
//NSArray *list = [[NSArray alloc]initWithArray:[parser objectWithString:jsonstring error:nil]];
NSDictionary *jsonDic = [[NSDictionary alloc]initWithDictionary:[parser objectWithString:jsonstring error:nil]];
prodNameLabel.text = [jsonDic objectForKey:@"name"];
prodIdLabel.text = [jsonDic objectForKey:@"prodId"];
prodPriceLabel.text = [NSString stringWithFormat:@"%@元",[jsonDic objectForKey:@"price"]];
adSloganLabel.text = [jsonDic objectForKey:@"adSlogan"];
//取出商品属性
[property1 release];
[property2 release];
[property3 release];
property1 = [[NSMutableArray alloc]init];
property2 = [[NSMutableArray alloc]init];
property3 = [[NSMutableArray alloc]init];
NSArray *templateInfoArray = [jsonDic objectForKey:@"prodSpecsPropTemplateInfo"];
//NSDictionary *templateInfDic = [templateInfoArray objectAtIndex:0];
propertyNumber = [templateInfoArray count];
for(int i=0;i<propertyNumber;i++)
{
NSDictionary *templateInfDic = [templateInfoArray objectAtIndex:i];
NSArray *propInfoArray = [templateInfDic objectForKey:@"prodExtendSpecsPropInfo"];
for(NSDictionary *propInfoDic in propInfoArray)
{
if(i==0)
{
[property1 addObject:[propInfoDic objectForKey:@"prodPropValue"]];
}
else if(i==1)
{
[property2 addObject:[propInfoDic objectForKey:@"prodPropValue"]];
}
else
{
[property3 addObject:[propInfoDic objectForKey:@"prodPropValue"]];
}
}
}
}
}
}
代码中我们只用了SBJson提供的SBJsonParser类,使用它我们可以将获得的JSON字符串交给库进行处理。获得经过处理的NSArray类型或者NSDictionary类实例。
从以上代码中我们可以层层推进获得JSON中任何一层的数据,避免了复杂的本地映射类的实现。