浅谈使用RestKit将服务器的Json直接映射为本地对象

来源:互联网 发布:mac os 10.10升级10.11 编辑:程序博客网 时间:2024/04/29 01:37

RestKit是一个主要用于iOS上网络通信的开源框架,除了发送请求与接受响应这些基本功能外,还附带coredata,以及将远程JSON映射为本地对象的功能。目前版本0.9.3,coredata还不是很稳定,他的coredata的demo页面在4.3.3实机下直接导致程序crash,但是其JSON映射为本地对象的功能是十分强大的。

首先,RestKit要求我们在客户端定义一个Model类,用于存储数据和处理业务逻辑。远程JSON中各键将直接映射为Model中各成员变量。对应每一个模型都要定义一个对应的Model类,这是强制的。

强制定义模型带来的好处是我们只需要写一次字典中的key,不再会因为字典的key拼错导致程序crash了。

RestKit使用起来省时省力,但是思维方式和ASIHTTP差异不小,以下举一例说明。

1、

假设服务器上的JSON数据如下:

{ "id": 1234, "name": "Personal Checking", "balance": 5013.26, "transactions": [ {"id": 1, "payee": "Joe Blow", "amount": 50.16}, {"id": 2, "payee": "Grocery Store", "amount": 200.15}, {"id": 3, "payee": "John Doe", "amount": 325.00}, {"id": 4, "payee": "Grocery Store", "amount": 25.15}] }

 

我们用来存储此JSON的对象的类名为SimpleAccount,其中包含六个成员:

_accountID用来对应JSON的id;

_name对应JSON的name;

_balance对应JSON的balance;

_transactionCount对应JSON的transactions数组中元素的数量;

_averageTransactionAmount对应JSON里transactions各元素的amount值的平均数;

_distinctPayees是将JSON里transactions中各元素的payee的值取出来后拼接而成的数组。

 

首先在Model的.h里定义好我们的数据成员,在.m里写好synthesize:

@interface SimpleAccount : NSObject { NSNumber* _accountID; NSString* _name; NSNumber* _balance; NSNumber* _transactionsCount; NSNumber* _averageTransactionAmount; NSArray*  _distinctPayees; } @property (nonatomic, retain) NSNumber* accountID; @property (nonatomic, retain) NSString* name; @property (nonatomic, retain) NSNumber* balance; @property (nonatomic, retain) NSNumber* transactionsCount; @property (nonatomic, retain) NSNumber* averageTransactionAmount; @property (nonatomic, retain) NSArray*  distinctPayees; @end @implementation SimpleAccount @synthesize accountID = _accountID; @synthesize name = _name; @synthesize balance = _balance; @synthesize transactionsCount = _transactionsCount; @synthesize averageTransactionAmount = _averageTransactionAmount; @synthesize distinctPayees = _distinctPayees; @end

2、

在恰当的时机(比如viewDidAppear中)做JSON键到Model成员变量的映射,然后开始请求数据。

@”id”,@”accountID”,把本Model中的accountID属性映射为JSON的id键对应的值;name和balance属性同理。

@”transactions.@count”,@transactionsCount”,取JSON中transactions数组的元素数。

@”transactions.@avg.amount”,@averageTransactionAmount”,取JSON中transactions的各元素的amount的值的平均数。

@”transactions.@distinctUnionOfObjects.payee”,@”distinctPayees”,将JSON里transactions中各元素的payee的值取出来后拼接而成的数组。

@”transactions.@avg.amount”这种写法比较诡异,可以理解成调用transactions对象的avg方法,传入参数是amount。

代码如下

RKObjectMapping* mapping = [RKObjectMapping mappingForClass:[SimpleAccount class]]; [mapping mapKeyPathsToAttributes: @"id", @"accountID", @"name", @"name", @"balance", @"balance", @"transactions.@count", @"transactionsCount", @"transactions.@avg.amount", @"averageTransactionAmount", @"transactions.@distinctUnionOfObjects.payee", @"distinctPayees", nil];

3、

定义好映射之后,就可以开始向服务器请求数据了。

[RKObjectManager sharedManager]返回一个单件的RKObjectManager。在初始化时向里面存入服务器的URL;

loadObjectResourcePath指定需要请求的JSON数据在服务器中的相对路径(服务器地址已经储存在RKObjectManage里,所以无需在此指定);

objectClass指定映射成的对象的类;

delegate指定接受回调的对象,在请求完成时,此对象的- (void)objectLoader:(RKObjectLoader*)objectLoader didLoadObjects:(NSArray*)objects会被调用。

- (void)workWithKVC { [[RKObjectManager sharedManager] loadObjectsAtResourcePath:@"/accounts.json" objectClass:[SimpleAccount class] delegate:self]; }

4、

最后是回调方法,若收到的JSON根为数组,则返回数组。根不是数组,则返回一个count为1的数组,所以回调收到的objects是NSArray*类型的。

- (void)objectLoader:(RKObjectLoader*)objectLoader didLoadObjects:(NSArray*)objects { SimpleAccount* account = [objects objectAtIndex:0]; // Will output "The count is 4" NSLog(@"The count is %@", [account transactionsCount]); // Will output "The average transaction amount is 150.115" NSLog(@"The average transaction amount is %@", [account averageTransactionAmount]); // Will output "The distinct list of payees is: Joe Blow, Grocery Store, John Doe" NSLog(@"The distinct list of payees is: %@", [[account distinctPayees] componentsJoinedByString:@", "]); }

参考资料http://mobile.tutsplus.com/tutorials/iphone/advanced-restkit-development_iphone-sdk/

以上

–OpenThread

0 0