iOS开发之优秀开源代码解读:RESTKit的使用教程

马上要开始一个关于体育赛事直播的新项目,数据逻辑比较复杂,数据处理这块如果按照以前的积累无疑会选择 AFNetworking+JSONKit+MagicalRecord.这种模式使用起来轻便,可定制性高,缺点就是在处理复杂数据时太费时间。考量得失和项目的需要,决定采用RestKit。其实RestKit在开源社区早就享有盛名,许多人会拿他和AFNetworking相互比较,在我看来两者侧重点不同,没有任何可比性。AFNetworking是一个功能非常齐全的网络数据请求库,侧重于处理各种类型的api风格,提供了远程图片异步加载,上传下载等常用功能,如果项目数据量很小它会是很好的选择。RestKit则是注重从远程数据请求到本地数据解析的存储和流程化业务处理,它专注于RESTful API,如果你项目服务器不是RESTful,那就别考虑了。RestKit包含json解析,object映射和coreData自动存储,很好很强大。如果你非要在这两者之间分个你死我活,请移步  RestKit-vs-AFNetworking-What-are-the-pros-and-cons 。 

之前并无使用RestKit的经验,摘录一篇觉得很不错的入门文章:

原文链接:  Introduction to RestKit Tutorial

翻译正文

你可以连接很多的web service(俗称web服务)来获取精彩有用的信息。举个例子,你可以通过Twitter的web service来获取list和发送Tweets,可以通过连接Foursquare的web service 来获取你附近的餐馆列表。如果你想用使用这些API,你可以直接使用NSURLRequest发起一个网络请求或者使用类似AFNetworking的库。然而还有一个更便捷的方法:使用RestKit!

RestKit是一个非常流行且便于使用的框架。它可以在处理api时候让你少写很多糟糕的代码,比如解析json和映射对象。

在这篇RestKit教程中,我们将要尝试使用FourSquare的api写一个简单的应用来实现现实附近咖啡馆的功能,因为我们都热爱和需要咖啡。

iOS开发之优秀开源代码解读:RESTKit的使用教程_第1张图片

开始

xcode中创建一个Master-View application,输入CoffeeKit作为工程名称,设置device为iPhone

使用RestKit

RestKit由三个部分组成

  • Network :RestKit现在使用AFNetworking v1.3.3作为网络操作层,RestKit的维护者正在升级到AFNetworking 2.0
  • Object Mapping(对象映射): RestKit提供一个接口来直接映射服务器返回的json/xml数据
  • Core Data:RestKit对coreData提供了额外的支持,包括映射远程对象为coreData对象并且进行本地存储

换句话说,这些工作的代码你都不用去写了!

最困难是事情就是安装和配置RestKit,可以选择两种方法:CocoaPods和Git submodule。我宁愿选择CocoaPods (  推荐CocoaPods教程 )。 

Podfile添加内容如下内容,重新pod install即可。

 
platform :ios, '5.0' pod 'RestKit', '~> 0.20.0'

在AppDelegate.m添加

 
#import <RestKit/RestKit.h>

运行项目,如果没有出错就是安装成功了。

连接Foursquare服务器

查询附近咖啡店需要用到api如下:

https://api.Foursquare.com/v2/venues/search?ll=37.33,-122.03&categoryId=4bf58dd8d48988d1e0931735

这个api返回json格式的数据,地点被写死在latitude: 37.33 and longitude: -122.03 ,大概是苹果的总部位置,categoryId是咖啡店的一个种类标识。

正常情况api会返回:

 
 {  "meta": {  "code": 200  },  "notifications": [  {  "item": {  "unreadCount": 3  },  "type": "notificationTray"  }  ],  "response": {  "confident": true,  "neighborhoods": [],  "venues": [  {  "categories": [  {  "icon": {  "prefix": "https://ss1.4sqi.net/img/categories_v2/food/coffeeshop_",  "suffix": ".png"  },  "id": "4bf58dd8d48988d1e0931735",  "name": "Coffee Shop",  "pluralName": "Coffee Shops",  "primary": true,  "shortName": "Coffee Shop"  }  ],  "contact": {  "formattedPhone": "(408) 446-9000",  "phone": "4084469000",  "twitter": "philzcoffee"  },  "hereNow": {  "count": 0,  "groups": []  },  "id": "51630409498eedc7dd88e60b",  "location": {  "address": "20686 Stevens Creek Blvd",  "cc": "US",  "city": "Cupertino",  "country": "United States",  "crossStreet": "De Anza Blvd",  "distance": 936,  "lat": 37.32246179607897,  "lng": -122.03470838696346,  "postalCode": "95014",  "state": "CA"  },  "name": "Philz Coffee",  "referralId": "v-1390061483",  "specials": {  "count": 0,  "items": []  },  "stats": {  "checkinsCount": 3790,  "tipCount": 40,  "usersCount": 1460  },  "verified": true  },  {  "categories": [  {  "icon": {  "prefix": "https://ss1.4sqi.net/img/categories_v2/food/coffeeshop_",  "suffix": ".png"  },  "id": "4bf58dd8d48988d1e0931735",  "name": "Coffee Shop",  "pluralName": "Coffee Shops",  "primary": true,  "shortName": "Coffee Shop"  }  ],  "contact": {  "formattedPhone": "(650) 321-2161",  "phone": "6503212161",  "twitter": "philz_coffee"  },  "hereNow": {  "count": 0,  "groups": []  },  "id": "4dd1580eb3adb047f5024231",  "location": {  "address": "101 Forest Ave",  "cc": "US",  "city": "Palo Alto",  "country": "United States",  "crossStreet": "at Alma St.",  "distance": 17063,  "lat": 37.442086282055726,  "lng": -122.16159119091502,  "postalCode": "94301",  "state": "CA"  },  "name": "Philz Coffee",  "referralId": "v-1390061483",  "specials": {  "count": 0,  "items": []  },  "stats": {  "checkinsCount": 14168,  "tipCount": 118,  "usersCount": 4044  },  "verified": true  }  ]  } } 

Foursquare提供一个免费的权限来使用他们的Foursquare,但是需要注册app(这和国内新浪等api使用流程相似)  注册页面

开始编码

首先把app的Client ID和Client Secret添加到MasterViewController.m

 
#define kCLIENTID @"Your Foursquare Client ID" #define kCLIENTSECRET @"Your Foursquare Client Secret

新建一个model命名为Venue,并在MasterViewController.m进行引用

 
@interface Venue : NSObject @property (nonatomic, strong) NSString *name; @end

在MasterViewController.m添加

 
- (void)viewDidLoad {  [super viewDidLoad];   [self configureRestKit];  [self loadVenues]; }   - (void)configureRestKit {  // initialize AFNetworking HTTPClient  NSURL *baseURL = [NSURL URLWithString:@"https://api.foursquare.com"];  AFHTTPClient *client = [[AFHTTPClient alloc] initWithBaseURL:baseURL];   // initialize RestKit  RKObjectManager *objectManager = [[RKObjectManager alloc] initWithHTTPClient:client];   // setup object mappings  RKObjectMapping *venueMapping = [RKObjectMapping mappingForClass:[Venue class]];  [venueMapping addAttributeMappingsFromArray:@[@"name"]];   // register mappings with the provider using a response descriptor  RKResponseDescriptor *responseDescriptor =  [RKResponseDescriptor responseDescriptorWithMapping:venueMapping  method:RKRequestMethodGET  pathPattern:@"/v2/venues/search"  keyPath:@"response.venues"  statusCodes:[NSIndexSet indexSetWithIndex:200]];   [objectManager addResponseDescriptor:responseDescriptor]; } 

RKObjectManager是和RESTful services交互的核心,需要一个AFHTTPClient实例来进行初始化。

RKObjectMapping是用来配置JSON和本地model的映射信息,如果json和本地的model中都有name这个字段,你又需要解析这个字段,那么就要通过addAttributeMappingsFromArray进行添加。

RKResponseDescriptor描述了对HTTP返回数据的映射信息。pathPattern 就是api的具体路径,会被添加到baseURL后面。keyPath 是对象在json数据中的路径。看看上面的json数据,@“response.venues”说明了对象venue所处的逻辑位置,并告诉RestKit去哪找venue。

在 MasterViewController.m添加venues来存储venue变量

 
@interface MasterViewController () @property (nonatomic, strong) NSArray *venues; @end @implementation MasterViewController

添加如下代码

 
- (void)loadVenues {  NSString *latLon = @"37.33,-122.03"; // approximate latLon of The Mothership (a.k.a Apple headquarters)  NSString *clientID = kCLIENTID;  NSString *clientSecret = kCLIENTSECRET;   NSDictionary *queryParams = @{@"ll" : latLon,  @"client_id" : clientID,  @"client_secret" : clientSecret,  @"categoryId" :  @"4bf58dd8d48988d1e0931735",  @"v" : @"20140118"};   [[RKObjectManager sharedManager] getObjectsAtPath:@"/v2/venues/search"  parameters:queryParams  success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {  _venues = mappingResult.array;  [self.tableView reloadData];  }  failure:^(RKObjectRequestOperation *operation, NSError *error) {  NSLog(@"What do you mean by 'there is no coffee?': %@", error);  }]; } 

这段代向服务器请求数据,getObjectsAtPath中传递的参数是@“/v2/venues/search”,所以RestKit就会自动查找并使用上文配置的RKResponseDescriptor来映射Venue对象.取到数据后tableView就会正确显示信息了。

iOS开发之优秀开源代码解读:RESTKit的使用教程_第2张图片

显示详细信息

我们想要在cell中显示咖啡店距离用户距离。 查看上文中的json数据,包含的距离的数据是

 
"location": {  "address": "20686 Stevens Creek Blvd",  "cc": "US",  "city": "Cupertino",  "country": "United States",  "crossStreet": "De Anza Blvd",  "distance": 936,  "lat": 37.32246179607897,  "lng": -122.03470838696346,  "postalCode": "95014",  "state": "CA" }

新建命名为Location的model

 
@property (nonatomic, strong) NSString *address; @property (nonatomic, strong) NSString *city; @property (nonatomic, strong) NSString *country; @property (nonatomic, strong) NSString *crossStreet; @property (nonatomic, strong) NSString *postalCode; @property (nonatomic, strong) NSString *state; @property (nonatomic, strong) NSNumber *distance; @property (nonatomic, strong) NSNumber *lat; @property (nonatomic, strong) NSNumber *lng;

在configureRestKit方法中添加

 
RKObjectMapping *locationMapping = [RKObjectMapping mappingForClass:[Location class]]; [locationMapping addAttributeMappingsFromArray:@[@"address", @"city", @"country", @"crossStreet", @"postalCode", @"state", @"distance", @"lat", @"lng"]];  // define relationship mapping [venueMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"location" toKeyPath:@"location" withMapping:locationMapping]]; 

通过上面的代码,当请求venue到数据后,可以直接通过venue.location.distance.floatValue来访问距离。 iOS开发之优秀开源代码解读:RESTKit的使用教程_第3张图片

这篇文章的例子中并未设计coreData对象的映射和存储,可以参照  官方文档 ,用法类似。

你可能感兴趣的:(Restful,RestKit,iOS数据处理,属性映射)