无线客户端框架设计(5.1):将JSON映射为实体对象(iOS篇)
iOS开发人员已经习惯于将JSON转换为字典或者数组来进行操作了,接下来我要做的事情,可能匪夷所思,但是,对WP和Android开发人员而言,他们更倾向于将JSON转换为实体对象进行操作。
我所设计的客户端框架,三个平台之间互相取长补短,保持统一的思想,而其中最重要的一环就是,面向对象的编程方式。
书接上文,我在异步调用完MobileAPI并成功获取到JSON后,仅仅将其转换为jsonValue,如下所示:

后续要做的事情,就是把jsonValue转换为实体对象了。
首先,要说一下JSON的格式。
MobileAPI返回的JSON字符串有几种格式:
1)单一实体:
a)简单属性:
{
"userName": "baobao",
"userAge": 18
}
b)属性中有复合属性,且该复合属性是另一个自定义实体:
{
"UserId": 1,
"UserInfo": {
"userName": "baobao",
"userAge": 18
}
}
c)属性中有复合属性,且该复合属性是一个数组:
{
"Career": "IT",
"Users": [
{
"userName": "Bill.Gates",
"userAge": 60
},
{
"userName": "baobao",
"userAge": 18
}
]
}
2)数组
a)规范的写法:
{
"Users": [
{
"userName": "Bill.Gates",
"userAge": 60
},
{
"userName": "baobao",
"userAge": 18
}
]
}
b)不规范的写法:
[
{
"userName": "Bill.Gates",
"userAge": 60
},
{
"userName": "baobao",
"userAge": 18
}
]
对以上格式进行归纳,我们发现,只需要指定好:
1)整个JSON字符串是规范的(这时是一个字典),还是不规范的(这时是一个数组)
2)对于规范的JSON字符串,每个JSON字段映射为实体的哪个字段,就是说,from是什么,to是什么?
3)实体字段的数据类型。对于JSON而言,简单类型,只有NSString和NSNumber两种(日期按字符串对待,布尔值按整数0和1对待)。复合类型,有2种:要么是一个自定义实体(这时是一个字典),要么是一个数组。
基于此,我们创建统一格式的实体格式如下:
//以下为UserEntity.h文件:
#import <Foundation/Foundation.h>
@class ObjectMapping;
@interface UserEntity : NSObject
{
NSString *name;
NSNumber *age;
}
@property (nonatomic,retain) NSString *name;
@property (nonatomic,retain) NSNumber *age;
- (ObjectMapping *)objectMapping;
@end
//以下为UserEntity.m文件:
#import "UserEntity.h"
#import "ObjectMapping.h"
@implementation UserEntity
@synthesize name;
@synthesize age;
- (ObjectMapping *)objectMapping {
ObjectMapping *mapping = [ObjectMapping mappingForClass:[UserEntity class]];
[mapping converEntityFromJsonToEntity:@"userName" to:@"name" withClass: @"NSString"];
[mapping converEntityFromJsonToEntity:@"userAge" to:@"age" withClass: @"NSNumber"];
return mapping;
}
- (void)dealloc {
[name release];
[age release];
[super dealloc];
}
@end
在格式统一的情况下,我们来讨论在MyApp中是如何使用的,参见APageViewController.m文件,我们继续改造上一节没有完成的requestFinished方法:

通过ObjectMappingLoader的loadObjectWithClassName方法,我们将jsonValue转换为实体result,然后再一次将result强制转换为WeatherWrapEntity类型的实体。接下来我们就可以使用weatherWrapEntity实体中的任何属性了,都是JSON里面返回的数据。
使用起来非常简单,但这一切都是MyLib类库下ObjectMapping目录中的3个类来实现的:

原理比较简单,使用到了迭代算法,把JSON格式的字符串先转换为字典,然后再迭代之,转换为实体。
本节源码如下: YoungHeart-Chapter-05-1.zip
另外,对各种情况的模拟,参见MyApp下的MyAppTest目录,这是一个单元测试,相应的Target为MyAppTests,每次修改MyLib的时候不是要把libMyLib.a重新引入到MyApp项目的MyApp这个Target中嘛,请同时将其也引入到MyAppTests这个Target中。
无线客户端框架设计(5.1):将JSON映射为实体对象(iOS篇)的更多相关文章
- 将JSON映射为实体对象(iOS篇)
将JSON映射为实体对象(iOS篇) iOS开发人员已经习惯于将JSON转换为字典或者数组来进行操作了,接下来我要做的事情,可能匪夷所思,但是,对WP和Android开发人员而言,他们更倾向于将JSO ...
- 无线客户端框架设计(3):基类的设计(iOS篇)
本文代码:YoungHeart-Chapter-03.zip 没有基类的App都不是好App. 因为iOS使用的是mvc模式的开发模式,所以,业务逻辑基本都在每个页面相应的ViewController ...
- 无线客户端框架设计(2):项目结构的设计(iOS篇)
本文附带源码:YoungHeart-Chapter-02.zip 在设计任何一个框架之前,都应规划好项目结构. 假定Git作为我们的项目管理工具.我们要建立两个仓库,一个用于存放我们的框架,另一个用于 ...
- 无线客户端框架设计(5):调用MobileAPI的设计(iOS篇)
这一节讲如何发起网络请求. iOS用于调用MobileAPI的第三方组件很多,我们这里采用的是以下组件: 1)ASIHTTPRequest,用于请求MobileAPI:http://allseeing ...
- 无线客户端框架设计(4):自定义生命周期的设计(iOS篇)
首先要确定一点,我们的App,要基于XIB文件进行编程,而不是在每个相应的ViewController里面去手动创建页面的每个控件.这样做的好处是,将页面布局与业务逻辑彻底隔离.于是我们可以把xib的 ...
- [Swift通天遁地]四、网络和线程-(11)将服务器返回的JSON映射为实例对象
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...
- JSON字符串转实体对象
JSON转实体两种方式 代码片段 ; i < dt.Rows.Count; i++) { //Json字符串 string designJson = dt.Rows[i]["Desig ...
- 浅谈使用RestKit将服务器的Json直接映射为本地对象
RestKit是一个主要用于iOS上网络通信的开源框架,除了发送请求与接受响应这些基本功能外,还附带coredata,以及将远程JSON映射为本地对象的功能.目前版本0.9.3,coredata还不是 ...
- 根据json生成java实体类
之前一篇讲过了XML转java实体对象,使用的是JAXB技术,今天给大家推荐一个在线转json到java实体对象: http://www.bejson.com/json2javapojo/new/ 转 ...
随机推荐
- __new__
[__new__] object.__new__(cls[, ...]) Called to create a new instance of class cls. 用于创建类对象cls的实例. __ ...
- 分享一个 jquery serializeArray()序列化方法
http://www.365mini.com/page/jquery-serializearray.htm http://www.365mini.com/diy.php?f=jquery-serial ...
- [原创]Matlab获取当前时间信息
本文主要介绍下Matlab中如何获取当前时间的一些方法. 基本变量date.now.clock date 按照日期字符串返回当前系统时间 now 按照连续的日期数值返回当前系统时间 clock按照日期 ...
- 問題排查:.NETSystem.Runtime.Remoting.RemotingException: TCP 信道协议冲突: 应为报头。
這個錯誤訊息是在一個 Web Serveice 的偵錯階段發生的 目前還未找到原因,環境如下: 作業系統:Windows 10 x64 企業版 (簡中) 開發工具:Visual Studio 2013 ...
- js资源
http://www.oschina.net/p/ace-editor https://git.oschina.net/pandao/editor.md/blob/master/editormd.js ...
- 更换光纤后路由器端口映射 -VPN相关
之前一直是ADSL的线路,使用路由器后,很简单就可以实现端口映射了!外网也可以随意连接,可是最近升级宽带更换了光纤后,发现怎么都不能正常工作了!在光纤猫里显示的IP居然是:10.0.*.*,查询到的外 ...
- 2227 邮票--FUoj(链接表+树的直径)
http://acm.fzu.edu.cn/problem.php?pid=2227 我感觉这道题可以随意搞 题目大意: 给你的一个图就是一条链,但是不知道起始点和结束点,而且每个点只会访问一次. 因 ...
- C++中new和malloc的区别
原文:http://blog.163.com/ji_wei8888/blog/static/4868044620117361747282/ 1.new 是c++中的操作符,malloc是c 中的一个函 ...
- 【洛谷P1541】乌龟棋
四维dp #include<cstdio> #include<cstring> using namespace std; ; ],a,b,c,d,n,m; int max(in ...
- Spring的定时任务配置(转)
spring的定时任务配置分为三个步骤: 1.定义任务 2.任务执行策略配置 3.启动任务 1.定义任务 <!--要定时执行的方法--> <bean id="testTas ...