如何在Odoo视图获取控制器数据库中获取JSON数据

如何使用iOS SDK获取和解析JSON数据 - 推酷
如何使用iOS SDK获取和解析JSON数据
文 / ziad tamim:资深iOS开发人员,创业公司移动战略咨询顾问。自App Store上线以来,编写超过80款应用程序。目前,他经营着一家叫做TAMIN LAB的移动开发工作室。
原文链接:
编辑注:本周,ziad tamim将向你展示如何获取和解析JSON数据。在本文中,我们会关注为iOS应用程序添加对JSON的支持,通过使用Meetup API来展示如何创建一个简单应用程序。这篇文章也许比我们之前介绍的其他文章要复杂一点儿,这正是你所需要的有关JSON和设计模式的基础知识。
JSON编程指南由此开始……
首先,什么是JSON?JSON(short for JavaScript Object Notation)是一个基于文本的,轻量级的,便于数据排序和交换的一种机制。通常用于在客户端/服务器模式的应用程序中表示结构化的数据,并进行数据的交互,作为XML格式数据的替代物。我们日常中所使用的很多服务都适用了基于JSON的API。大多数iOS应用程序都使用JSON格式的网络服务将数据发送到它们的后端web服务。包括Twitter,Facebook和Flick在内都是这样做的。
&title&: &The Amazing Spider-man&,
&release_date&: &03/07/2012&,
&director&: &Marc Webb&,
&name&: &Andrew Garfield&,
&character&: &Peter Parker&
&name&: &Emma Stone&,
&character&: &Gwen Stacy&
&name&: &Rhys Ifans&,
&character&: &Dr. Curt Connors&
不难发现,JSON数据比XML更具可读性,更容易解析。如果你对JSON一无所知,可以看看这个
iOS5发布以来,iOS SDK更容易获取和分析JSON数据。在这篇文章中,我们将展示如何使用内置API查询来自
基于JSON的API,并恰当地处理返回值。
我们的应用程序
编写代码以前,先来看看要构建什么样的应用程序。
在本文中,我们要创建一个叫做BrowserMeetup的简单应用程序,将会使用Meetup的公共API。从来没听说过Meetup吗,它是全球最大的本地聚会网络平台。你可以免费使用它来组织在当地的聚会,还可以从上千个已经组织好的聚会中找到其中的一个。像其他社交网站一样,Meetup为你的服务端访问其数据提供了开放API。
BrowseMeetup应用程序会使用
来寻找附近的聚会。应用程序会获得当前的地理位置并自动加载附近的聚会。
注:该应用程序使用Core Location框架,如果你不了解该框架,可以参考
动手开发应用程序
可以开始构建和管理BrowseMeetup应用程序了。启动Xcode并创建一个主-从视图类型的应用程序(Master-Detail Application)。项目选项设置中,你要选择Storyboard和ARC(Automatic Reference Counting)选项。该应用仅提供iPhone视图,因此在设备选项中选择iPhone并保存项目。删除掉storyboard中的DetailsViewController,像下面这样设计用户界面:
本文着重介绍JSON的获取和解析。所以为了节省时间就不去建立项目了,你可以直接下载
。模版已经事先构建好了用户接口并实现了Core Location功能。
提示:如果不懂怎么用table view,想知道导航条是如何工作的,可以参考我们
使用Meetup的API
使用Meetup API前,请在其上先创建一个账号。打开
,点击“Request to join this Meetup group”按钮。然后填写必要的信息,点击“Sign Up”。一步一步进行直至完成。
我们将使用其中的一个API(/2/groups)来获取在某个地点举行的Meetup聚会信息。调用过程允许开发者使用经纬度来定位。可以使用
来测试调用。
这是一段请求后简单的JSON响应信息(/2/groups?&sign=true&lat=51.509980&lon=-0.133700&page=1):
&results&: [
&lon&: -0.11612,
&visibility&: &public&,
&organizer&: {
&name&: &William Brown&,
&member_id&: 3817216
&link&: &/french-32/&,
&state&: &17&,
&join_mode&: &approval&,
&who&: &LFM members&,
&country&: &GB&,
&city&: &London&,
&id&: 63974,
&category&: {
&name&: &language/ethnic identity&,
&shortname&: &language&
&topics&: [
&id&: 185,
&urlkey&: &french&,
&name&: &French Language&
&id&: 264,
&urlkey&: &friends&,
&name&: &Friends&
&id&: 3304,
&urlkey&: &expatfrench&,
&name&: &Expat French&
&timezone&: &Europe/London&,
&group_photo&: {
&photo_link&: &/photos/event/7/4/a/b/600_929867.jpeg&,
&highres_link&: &/photos/event/7/4/a/b/highres_929867.jpeg&,
&thumb_link&: &/photos/event/7/4/a/b/thumb_929867.jpeg&,
&photo_id&: 929867
&created&: 0,
&description&: &&p&The London French Meetup is the biggest group of French speakers of all ages and nationalities in London. We hold regular events to meet up, talk in French and share interests in French culture whilst having a good time.&/p&
&p&We have two main events per month where we have the whole of the upstairs of a pub.&/p&
&p&In addition, we organise other regular events such as outings to: restaurants, trendy bars, french films, live music, sports related activities, outdoor events and more...&/p&
&p&The organising team is made of volunteers from different nationalities and ages. Our members are made up of: 1/3 French nationals, 1/3 British nationals and 1/3 other nationalities and francophone countries. If you have any ideas or suggestions for events or would like to help please let us know.&/p&
&p&A bient&t.&/p&
&p&LFM Team.&/p&&,
&name&: &London French Meetup&,
&rating&: 4.37,
&urlname&: &french-32&,
&lat&: 51.67,
&members&: 4889
&lon&: -0.1337,
&count&: 1,
&signed_url&: &/2/groups?radius=25.0o=id&desc=false&offset=0&format=json?=51.50998&page=1&fields=&lon=-0.1337&sig_id=&sig=f940748ebfba0f483a26f756dcba3&,
&link&: &/2/groups&,
&next&: &/2/groups?radius=25.0o=id&format=json?=51.50998&page=1&desc=false&offset=1&fields=&sign=true&lon=-0.1337&,
&total_count&: 4501,
&url&: &/2/groups?radius=25.0o=id&format=json?=51.50998&page=1&desc=false&offset=0&fields=&sign=true&lon=-0.1337&,
&title&: &Meetup Groups v2&,
&updated&: 0,
&description&: &&&&,
&method&: &Groups&,
&lat&: 51.50998
应用程序设计及工作原理
如前所述,Meetup API提供了请求某方位聚会信息的
。响应数据将用JSON格式发送。我们需要一个对象,可以从已编码的数据中检索数据,并从中构建我们的域对象(domain object )。下面是关于应用程序设计的介绍,展示如何构建类,以及这些类如何获得meetup聚会信息:
对于有些人来说,也许有点儿复杂。我来带你过一遍。创建MeetupManager是为了请求的Meetup聚会所获得的方位,就像门面一样。如果你没有听说过设计模式中的门面模式(Facade Pattern)的话,可以把它想象成其他类的协调者。门面模式试图为界面试图控制器提供一个简化的接口,并屏蔽掉底层的实现。
MeetupCommunicator用来与Meetup API进行通讯。一旦Meetup返回JSON格式响应,我们就将该响应传递给GroupBuilder,GroupBuilder构建了Group对象。
MasterViewController使用
得到当前的方位,并通知MeetupManager得到该方位的Meetup聚会信息。MeetupManager协调其他的类来检索得到的那些聚会信息。一旦检索成功,MeetupManager会通过代理与MasterViewController通信,并将检索到的聚会信息传递过去。然后MasterViewController将传递过来的聚会信息在table view中展现出来。
创建JSON数据模型
接下来我们将要实现实体类(model层)。Group类表示BrowseMeetup应用中聚会的信息,用来存储从Meetup返回的聚会信息。下面是一个JSON响应中的Group对象示例:
lon: -71.97,
visibility: &public&,
organizer: {
name: &Emma&,
member_id: 2161382
link: &/bloggers/&,
state: &MA&,
join_mode: &closed&,
who: &Bloggers&,
country: &US&,
city: &Cambridge&,
id: 21458,
category: {
name: &tech&,
shortname: &tech&
urlkey: &blog&,
name: &Blog&
urlkey: &writers&,
name: &Writers&
timezone: &US/Eastern&,
group_photo: {
photo_link: &/photos/event/6/4/9/5/600_25749.jpeg&,
highres_link: &/photos/event/6/4/9/5/highres_25749.jpeg&,
thumb_link: &/photos/event/6/4/9/5/thumb_25749.jpeg&,
photo_id: 25749
created: 0,
description: &This is a group for people that are interested in blogging and meeting others who are interested in blogging. Topics discussed range from blog content to blog software. All interest levels are welcome.&,
name: &The Greater Boston Area Weblogger Meetup Group&,
rating: 3.33,
urlname: &bloggers&,
lat: 42.44,
members: 119
上面的JSON响应代表单个Meetup Group。我们不会使用所有返回来的数据。而是简单地使用“name”,“description”,“who”,“country”和“city”字段。这些字段对我们来说足够了。现在要使用Objective-C类模版来创建一个新文件,命名为Group,将它设置为NSObject的子类,并在头文件中添加如下代码:
@interface Group : NSObject
@property (strong, nonatomic) NSString *
@property (strong, nonatomic) NSString *
@property (strong, nonatomic) NSString *
@property (strong, nonatomic) NSString *
@property (strong, nonatomic) NSString *
我们将使用这些属性信息,在应用程序中实现我们之前描述的最终结果。
使用Meetup API获取JSON 数据
首先,使用Objective-C的协议模版创建一个文件,并命名为MeetupCommunicatorDelegate,在文件中填充如下代码:
@protocol MeetupCommunicatorDelegate
- (void)receivedGroupsJSON:(NSData *)objectN
- (void)fetchingGroupsFailedWithError:(NSError *)
MeetupCommunicator类负责Meetup API在获取JSON数据过程中的通讯。它依赖于MeetupCommunicatorDelegate来处理解析JSON数据的任务。通讯类本身并不知道JSON数据是如何被处理的。通讯类只关心为Meetup API和获取JSON原始结果数据的过程创建连接。
代理被创建以后,创建另一个类文件,并命名为MeetupCommunicator。打开头文件,键入如下代码:
#import &CoreLocation/CoreLocation.h&
@protocol MeetupCommunicatorD
@interface MeetupCommunicator : NSObject
@property (weak, nonatomic) id&MeetupCommunicatorDelegate&
- (void)searchGroupsAtCoordinate:(CLLocationCoordinate2D)
我们创建了一个属性,用来跟踪记录通讯代理。然后定义了一个方法,用来查找特定方位的聚会信息。接下来,打开MeetupCommunicator.m文件,替换成如下代码:
#import &MeetupCommunicator.h&
#import &MeetupCommunicatorDelegate.h&
#define API_KEY @&1ffb3a2&
#define PAGE_COUNT 20
@implementation MeetupCommunicator
- (void)searchGroupsAtCoordinate:(CLLocationCoordinate2D)coordinate
NSString *urlAsString = [NSString stringWithFormat:@&/2/groups?lat=%f&lon=%f&page=%d&key=%@&, coordinate.latitude, coordinate.longitude, PAGE_COUNT, API_KEY];
NSURL *url = [[NSURL alloc] initWithString:urlAsString];
NSLog(@&%@&, urlAsString);
[NSURLConnection sendAsynchronousRequest:[[NSURLRequest alloc] initWithURL:url] queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
if (error) {
[self.delegate fetchingGroupsFailedWithError:error];
[self.delegate receivedGroupsJSON:data];
Meetup API需要一个key来工作。如果你注册了账号,需要从
页面得到key的话,那么简单地点击一下文本框旁边的��图标就可以得到key。把里面的文本拷贝出来,用自己的API key将API_KEY宏的值替换掉。
正如上面提到的,我们使用下面的Meetup API来查找指定方位的聚会信息。API接受经纬度格式的方位信息。下面就是Meetup URL连接的示例:
/2/groups?lat=51.509980&lon=-0.133700&page=20&key=1ffb3a2
在方法的实现中,我们首先使用特定的经纬度,以及聚会的数量和API key来构建API URL。为了在UI部分不卡住,我们通过使用
中的“sendAsynchronousRequest:”方法为URL请求异步加载数据。最终检索到JSON数据,将它传递给代理进一步进行处理。
解析JSON数据并绑定Group对象
MeetupManager收到JSON格式的数据时,使用GroupBuilder的类方法将数据转换为Group对象。使用Objective-C类模版创建一个新文件,命名为GroupBuilder。打开头文件,粘贴如下代码:
#import &Foundation/Foundation.h&
@interface GroupBuilder : NSObject
+ (NSArray *)groupsFromJSON:(NSData *)objectNotation error:(NSError **)
接下来,打开“GroupBuilder.m”文件,实现对应的方法:
#import &GroupBuilder.h&
#import &Group.h&
@implementation GroupBuilder
+ (NSArray *)groupsFromJSON:(NSData *)objectNotation error:(NSError **)error
NSError *localError =
NSDictionary *parsedObject = [NSJSONSerialization JSONObjectWithData:objectNotation options:0 error:&localError];
if (localError != nil) {
*error = localE
NSMutableArray *groups = [[NSMutableArray alloc] init];
NSArray *results = [parsedObject valueForKey:@&results&];
NSLog(@&Count %d&, results.count);
for (NSDictionary *groupDic in results) {
Group *group = [[Group alloc] init];
for (NSString *key in groupDic) {
if ([group respondsToSelector:NSSelectorFromString(key)]) {
[group setValue:[groupDic valueForKey:key] forKey:key];
[groups addObject:group];
方法“groupsFromJSON”被设计为将原始的JSON数据转换成Group对象的数组。iOS 5发布以来,iOS SDK中名为NSJSONSerialization的类用来解析JSON数据。开发人员使用该类可以将JSON数据转换成Foundation框架中的对象,也可以将Foundation框架中的对象转回JSON数据。
当使用NSJSONSerialization读取JSON数据时,所有的键列表(keyed list)都被自动转换成NSDictionary对象。数组则会被转换为NSArray实例。键列表中任何带有已命名项名称的字符串都会被转换为NSString,而纯数字字符串会被转换为NSNumber对象。最后,任何为空的值都会被用NSNull表示。
在本文前面部分向你展示的响应示例中,Meetup API返回的JSON响应包括两部分,结果数据和元(meta)信息。而我们只需要“结果”部分。代码相当直观明了,我们循环遍历了所有的结果,查看了其中的每一个NSDictionary。然后创建了Group对象,对其填充了必要信息,然后将Group对象添加到可变数组当中。
用MeetupManager把各部分集中起来
你现在应该明白JSON是如何工作的了,如何解析数据并将数据转换成对象。接下来,我们要实现MeetupManager,作为底层类的协调者来使用。
首先,使用Objective-C协议模版创建一个文件,命名为MeetupManagerDelegate。在MeetupManagerDelegate.h文件中添加如下代码:
@protocol MeetupManagerDelegate
- (void)didReceiveGroups:(NSArray *)
- (void)fetchingGroupsFailedWithError:(NSError *)
这个代理声明了两个方法,当group对象需要的时候会被MeetupManager调用。当从Meetup响应中检索到的group列表被解析时,调用第一个方法。而当发生错误的时候,第二个方法会被调用。MeetupManagerDelegate将会被MasterViewController实现,我们会在随后内容中讲解。
接下来,使用Objective-C类模版创建一个新文件,命名为MeetupManager。打开头文件,添加如下代码:
#import &Foundation/Foundation.h&
#import &CoreLocation/CoreLocation.h&
#import &MeetupManagerDelegate.h&
#import &MeetupCommunicatorDelegate.h&
@class MeetupC
@interface MeetupManager : NSObject&MeetupCommunicatorDelegate&
@property (strong, nonatomic) MeetupCommunicator *
@property (weak, nonatomic) id&MeetupManagerDelegate&
- (void)fetchGroupsAtCoordinate:(CLLocationCoordinate2D)
前面说过,MeetupManager扮演着门面的角色。应用程序的控制器可与实体类(Group)一起工作,不需要知道任何关于网络连接的细节,也不需要知道JSON如何获取和解析,以及group对象如何创建。控制器需要知道的仅仅是使用“fetchGroupsAtCoordinate:”方法获取Meetup聚会的信息。
我们设置一个属性来记录稍后要用到的communicator实例,还有用来追踪MeetupManagerDelegate的属性。“fetchGroupsAtCoordinate:”方法将被控制器用来获取group。
下一步,打开MeetupManager.m文件,替换成下面的代码:
#import &GroupBuilder.h&
#import &MeetupCommunicator.h&
@implementation MeetupManager
- (void)fetchGroupsAtCoordinate:(CLLocationCoordinate2D)coordinate
[municator searchGroupsAtCoordinate:coordinate];
#pragma mark - MeetupCommunicatorDelegate
- (void)receivedGroupsJSON:(NSData *)objectNotation
NSError *error =
NSArray *groups = [GroupBuilder groupsFromJSON:objectNotation error:&error];
if (error != nil) {
[self.delegate fetchingGroupsFailedWithError:error];
[self.delegate didReceiveGroups:groups];
- (void)fetchingGroupsFailedWithError:(NSError *)error
[self.delegate fetchingGroupsFailedWithError:error];
在这里实现了fetchGroupsAtCoordinate:coordinate方法,通过使用communicator的searchGroupsAtCoordinate:coordinate方法来获取group。还实现了MeetupCommunicatorDelegate下面的那些方法,用来处理communicator检索到的JSON格式的结果。
协议receivedGroupsJSON:objectNotation第一个方法中代码使用GroupBuilder的类方法将JSON数据填入Group对象,然后将Group对象通知给方法的代理。如果在处理请求的过程中出现任何问题,我们就调用代理的另一个方法(fetchingGroupsFailedWithError)来通知控制器,让控制器知道出现了问题。
显示Group列表
首要任务就是要把这些类都拿来放到一起让MeetupManager能够工作。打开MasterViewController.m文件,导入所需的头文件,更新接口,并且声明MeetupManager实例:
#import &Group.h&
#import &MeetupManager.h&
#import &MeetupCommunicator.h&
@interface MasterViewController () &MeetupManagerDelegate& {
NSArray *_
MeetupManager *_
随后我们就要实现在MeetupManagerDelegate中所定义的方法。但首先我们先在viewDidLoad方法中要实例化MeetupManager:
- (void)viewDidLoad
[super viewDidLoad];
_manager = [[MeetupManager alloc] init];
_municator = [[MeetupCommunicator alloc] init];
_municator.delegate = _
_manager.delegate =
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(startFetchingGroups:)
name:@&kCLAuthorizationStatusAuthorized&
object:nil];
正在实例化一个新的manager,然后用一个新的实例给它的communicator属性赋值,最后让当前的视图控制器追踪一切变化。当警告弹出告诉用户使用定位服务开始,就调用startFetchingGroups:方法从服务端获取group,这里的观察者(observer)会捕捉一切用户的响应。
接下来,打开“MasterViewController.m”,键入如下代码开始获取信息:
- (void)startFetchingGroups:(NSNotification *)notification
[_manager fetchGroupsAtCoordinate:self.locationManager.location.coordinate];
由于视图控制器应该遵循MeetupManagerDelegate协议,所以要实现其中的方法:
- (void)didReceiveGroups:(NSArray *)groups
[self.tableView reloadData];
- (void)fetchingGroupsFailedWithError:(NSError *)error
NSLog(@&Error %@; %@&, error, [error localizedDescription]);
当从Meetup服务端返回的实例中获得了Meetup聚会信息,将调用“didReceiveGroups:”方法。我们这里要做的是简单地在table view里面显示新数据。
最后,构建table view的相关方法:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
return _groups.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
DetailCell *cell = [tableView dequeueReusableCellWithIdentifier:@&Cell& forIndexPath:indexPath];
Group *group = _groups[indexPath.row];
[cell.nameLabel setText:group.name];
[cell.whoLabel setText:group.who];
[cell.locationLabel setText:[NSString stringWithFormat:@&%@, %@&, group.city, group.country]];
[cell.descriptionLabel setText:group.description];
上段代码非常直观,我们从数组中检索那些group,然后将group的信息填入表格中。
编译和运行
现在,可以测试这个应用程序了。在模拟器中编译并运行(如果注册了iOS开发者计划,可以使用真实的iOS设备)。将模拟器的位置设置为英国伦敦,你就会得到像下面截屏中的Meetup聚会信息了。
提示:如果你不了解iPhone模拟器中的方位测试,可以看看
在本文中,我们通过采用与JSON数据相配的设计模式,讲解了编程的很多方面,你应该具有了获取和解析JSON数据的实践经验。
如果你对设计模式是生手,这篇文章可能稍许复杂。但这不应该难住你而放弃在应用程序中使用JSON。iOS的SDK让这一过程变得容易了。总之就是,简简单单地创建一个URL连接,通过内置的NSJSONSerialization类获取和解析JSON数据。
在网上可以找到各种各样的免费API(比如
)。当作练习,尝试使用另一个API再开发一款应用程序。也就是说,你可以使用Kiva API开发一款显示近期筹贷款列表简单应用程序。
作为参考,可以在这里
已发表评论数()
请填写推刊名
描述不能大于100个字符!
权限设置: 公开
仅自己可见
正文不准确
标题不准确
排版有问题
主题不准确
没有分页内容
图片无法显示
视频无法显示
与原文不一致本帖子已过去太久远了,不再提供回复功能。

我要回帖

更多关于 odoo jsonrpc 的文章

 

随机推荐