导航

RestKit学习5:Loading Remote Objects

Posted on 2012-09-04 11:38  蝈蝈俊  阅读(718)  评论(0编辑  收藏  举报

本系列的前面几篇:

RestKit学习1:引用RestKit项目
RestKit学习2:使用RestKit发送和接受请求 
RestKit学习3:CoreData 从模型到实体
RestKit学习4:Database Seeding(生成数据库文件)

这篇是从服务器的一个json接口直接获得数据,并把数据解析成对象。

需要解析的json字符串:

{"error":0,"message":"成功","list":[{"id":1,"name":"传祺","domestic":"国产","logo_ext":"jpg","logo_hash":"4081269f8b182a263b2e881e6c402a5c","seating":5},{"id":2,"name":"传祺GS5","domestic":"国产","logo_ext":"jpg","logo_hash":"b6da2a07ccd3ba7e48e0284524509a64","seating":5},{"id":3,"name":"E系列","domestic":"国产","logo_ext":null,"logo_hash":"d41d8cd98f00b204e9800998ecf8427e","seating":5},{"id":4,"name":"D系列","domestic":"进口","logo_ext":null,"logo_hash":"d41d8cd98f00b204e9800998ecf8427e","seating":3},{"id":5,"name":"V系列","domestic":"国产","logo_ext":null,"logo_hash":"d41d8cd98f00b204e9800998ecf8427e","seating":3}]}

json串对应的实体设置

注意图中的提示,一些保留字不应该出现。

Snip20120904 2

如果中间出现错误:

“*** Assertion failure in -[RKManagedObjectMapping initWithEntity:] Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'The managedObjectClass for an object mapped entity cannot be nil.'”时,解决方法是DataModel.xcdatamodel重新生成一下实体类。

项目的引用看前面的文章。

AppDelegate.m 中Code

定义服务的地址,定义实体类跟json的映射关系

//

//  AppDelegate.m

//  testRestKit02

//

//  Created by cybercare on 12-7-30.

//  Copyright (c) 2012 cybercare. All rights reserved.

//

 

#import "AppDelegate.h"

#import <RestKit/RestKit.h>

#import <RestKit/CoreData.h>

 

#define DBNAME @"BAWSeed.sqlite"

 

 

@implementation AppDelegate

 

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

{

    // Setup the object manager

    RKObjectManager* objectManager = [RKObjectManagerobjectManagerWithBaseURLString:@"http://www.in4s.cn:8080/Inpads/android/"];

    

    // 需要存储的文件名

    objectManager.objectStore = [RKManagedObjectStoreobjectStoreWithStoreFilename:DBNAME];

    

    // json 文件和 Core Data对象属性映射关系。

    RKManagedObjectMapping* mapping = [RKManagedObjectMappingmappingForEntityWithName:@"Series"inManagedObjectStore:objectManager.objectStore];

    

    mapping.primaryKeyAttribute = @"sid";

    mapping.rootKeyPath = @"list";

    

    [mapping mapKeyPath:@"id"toAttribute:@"sid"];

    [mapping mapKeyPath:@"name"toAttribute:@"sname"];

    [mapping mapKeyPath:@"domestic"toAttribute:@"domestic"];

    [mapping mapKeyPath:@"logo_ext"toAttribute:@"logo_ext"];

    [mapping mapKeyPath:@"logo_hash"toAttribute:@"logo_hash"];

    [mapping mapKeyPath:@"seating"toAttribute:@"seating"];

    

    // Register our mappings with the provider

    [objectManager.mappingProvidersetObjectMapping:mapping forResourcePathPattern:@"/sync/series"];

    

 

    #ifdef RESTKIT_GENERATE_SEED_DB

        // 需要生成数据库时用

        // Load all the data from the file series.json into a seed database

        // The seeder will print instructions for how to copy the data to your app

    

        RKManagedObjectSeeder * seeder = [RKManagedObjectSeederobjectSeederWithObjectManager:objectManager];

    

        [seeder seedObjectsFromFile:@"series.json"withObjectMapping:mapping];

        [seeder finalizeSeedingAndExit];

    #endif

 

    returnYES;

}

 

 

- (void)applicationWillResignActive:(UIApplication *)application

{

}

 

- (void)applicationDidEnterBackground:(UIApplication *)application

{

}

 

- (void)applicationWillEnterForeground:(UIApplication *)application

{

}

 

- (void)applicationDidBecomeActive:(UIApplication *)application

{

}

 

- (void)applicationWillTerminate:(UIApplication *)application

{

}

 

 

 

@end

 

ViewController.m 中 Code

点击一个按钮是,向服务器的服务发送请求,并获得对象实例。

 

//

//  ViewController.m

//  testRestKit02

//

//  Created by cybercare on 12-7-30.

//  Copyright (c) 2012 cybercare. All rights reserved.

//

 

#import "ViewController.h"

#import <RestKit/RestKit.h>

#import "Series.h"

 

@interfaceViewController ()

 

@end

 

@implementation ViewController

 

- (void)viewDidLoad

{

    [superviewDidLoad];

}

 

- (void)viewDidUnload

{

    [superviewDidUnload];

}

 

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation

{

    return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);

}

 

 

#pragma mark RKObjectLoaderDelegate methods

 

- (void)objectLoader:(RKObjectLoader*)objectLoader didLoadObjects:(NSArray*)objects {

   

    NSLog(@"4444" );

    

    if ([objectLoader wasSentToResourcePath:@"/sync/series"]) {

 

        for(Series* item in objects)

        {

            NSLog(@"%@,%@",item.sid,item.sname);

        }

    }

}

 

- (void)objectLoader:(RKObjectLoader*)objectLoader didFailWithError:(NSError*)error {

    UIAlertView* alert = [[UIAlertViewalloc] initWithTitle:@"Error"

                                                     message:[error localizedDescription]

                                                    delegate:nil

                                           cancelButtonTitle:@"OK" otherButtonTitles:nil] ;

    [alert show];

    NSLog(@"Hit error: %@", error);

    NSLog(@"Rats! Failed to load objects: %@", [error localizedDescription]);

 

}

 

- (void) ButtonWasPressed:(id)sender {

    

    RKObjectManager * objectManager = [RKObjectManagersharedManager];

    

    [objectManager loadObjectsAtResourcePath:@"/sync/series"delegate:self];

}

 

 

@end

 

 

这个过程中发生了什么?

1、在 AppDelegate.m 中配置json对象跟实体类的映射关系,在AppDelegate.m中定义是为了重复利用;
2、异步向服务器发送请求 loadObjectsAtResourcePath
3、服务器返回200,以及JSON body
4、RKObjectMapper parsed payload and mapped JSON data to 实体类
5、Callback invoked with array of Contacts

 

参考资料:

https://github.com/RestKit/RestKit/wiki/Tutorial-%3A-Introduction-to-RestKit