zoukankan      html  css  js  c++  java
  • 浅谈使用RestKit将服务器的Json直接映射为本地对象

    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

  • 相关阅读:
    iOS中循环引用的解除
    Block的循环引用详解
    Mac OS X下面 Node.js环境的搭建
    swift中闭包和OC的block的对比
    STL priority_queue
    优先使用map(或者unordered_map)的find函数而非algorithm里的find函数
    Insert Interval
    Integer Break
    Unique Binary Search Trees
    腾讯2016实习生笔试
  • 原文地址:https://www.cnblogs.com/zsw-1993/p/4879570.html
Copyright © 2011-2022 走看看