iOS 数据解析 JSONModel的介绍

 ·

    IOS设备时常需要和服务器----一般来说是远程服务器进行数据交换。轻量级的APP应用只需少量的数据交互,例如每小时获取一次是否有更新的消息。另一些APP应用则需要与后台服务器有类似分享信息,阅读关注,Po一张照片等操作。

    用XML来发送这些信息给Web服务器已经过时了。越来越多的移动应用更倾向于用JSON这种数据格式。一旦计划开发移动应用的并有与后台通信的需求,则要用JSON数据格式与服务器通信。

    JSPNModel是用Objective-C写的开源库。它包含了接受发送、解析JSON数据,用JSON数据驱动初始化你的类,还能够检验JSON和嵌套模型等功能。



jm1_8_logo.png




巧豆麻袋!你也许在想,我已经在APP里使用JSON数据格式,这太简单了。好吧,话是没错,NSJSONSerialization在iOS 5的时候就存在了。它能够很容易的就把JSON转换成一个NSDictionary对象,对于程序来说这很简单。但是在一个复杂的应用里处理一些复杂的数据模型的时候,就显得很乏力了。那么来看看JSONModel是如何帮你脱离苦海的吧。


作为JSONModel的作者,我很乐意你们来帮我一起改进提高JSONModel,这么说有点自私,但同样让你得到学习和提高。contributors on GitHub



基础入门


这一节将向您介绍JSONModel的一些基础知识,如果您想更快的看到代码或深入的学习,您可以选择跳过本章直接进入Hello App的部分。


将JSON转换成一个模板类

jm1_11_matchingclass.png

当你需要将一个JSON转换成一个模板类时,你第一时间可能会想用Key和Names的对应关系这样去写:

  1. self.firstName = [json objectForKey:@"firstName"];
  2. self.familyName = [json objectForKey:@"familyName"];
  3. self.age = [json objectForKey:@"age"];
复制代码

JSONModel则能自动的将JSON格式的数据映射成一个样板代码,定义好所需的属性和值。


输入验证

JSONModel会自动验证一个JSON数据是否能够映射成一个模板类,确保与类的定义相匹配,如果有一个不匹配,则不会初始化成功。另外,还会检测定义的类型是否一致,例如,如果你将一个array映射成一个string,那么这个JSON数据将会被视为无效。


    类型转换    由于JSON数据本身类型比较简单规范,所以同后台的数据类型相比,它少了很多元数据类型,与后台通信时就不能按照这些类型保存。JSON只能使用字符、数字、数组、或是对象。

jm1_9_types.png



    在Objective-C中会有很多类型,不仅仅只是限于字符或数字,但可惜的是JSON只支持这些。举例来说,在JSON里经常有URLs的数据,你可以通过string类型来保存和传输,你也可以很容易的就把它转换成一个NSURL对象,但是每一次都要自己手动做这些不是很恼火么。而在JSONModel里,你只需要定义一次不同类型之间的转换规则,就可以自动帮你完成数据转换。比如,在JSON有一个整形来表示一个时间戳,你只需要告诉JSONModel一次,如何将一个整形转换成一个NSDate,在下一次和以后的传输过程中,它都会自动被转换。在第二部分会更详细的介绍这个内容。

    嵌套模式
    很多时候JSON数据是一个复杂的结构,它可能包含一个或多个JSON数据。就像这个JSON数据一样:

  1. {
  2.     "id": 10,
  3.     "more": { 
  4.         "text": "ABC",
  5.         "count": 20
  6.     }
  7. }
复制代码
    不用担心,就算遇到这种情况,JSONModel依旧能够把它映射成一个模板类,当你的模板类内部包含另一个模板类或是类型的时候,JSONModel依旧能够正常工作,稍后再看看更详细嵌套模式的介绍。

    想必这些简单的介绍已经足够让你了解JSONModel的基础了,下面通过一个简单的应用实例来讲解如何使用JSONModel。

The Hello Chuck App
    现在已经基本了解JSONModel的功用,设想一下创建一个类似“冷笑话精选”这种类型的APP,让用户可以一条一条的看冷笑话。最终效果如下:

jm1_10_completedapp.png


步骤1:创建项目


  
    启动XCode5,创建一个新的iOS应用:选择New > ProjectFile菜单里,选择Single View Application的iOS 模板。


figure-1.png 

    项目名称就用HelloChuck,选择保存位置,项目不需要添加源码管理。


figure-2.png 

    创建完项目后,从Git上下载JSONModel库文件,解压缩后得到文件。

jm1_3_jmfiles.png 

    解压缩出来有iOS的例子,单元测试工具,文档说明等内容,现在所需要的就是JSONModel文件夹,把它拖入到HelloChuck项目里,如果你有CocoaPods的话,安装会变得更容易些。


    步骤2:建立模板类

    JSON格式的源数据非常简单,有一个笑话的数组,每个数组的元素包含笑话的id,笑话的本身的内容,笑话的可选标签。
  1. {
  2.     "id": 7,
  3.     "text": "There used to be a street named after Chuck Norris but it was changed because nobody crosses Chuck Norris and lives",
  4.     "tags": [
  5.         { "id":1, "tag":"lethal" },
  6.         { "id":2, "tag":"new" }
  7.     ]
复制代码

    现在我们开始用这个JSON数据建立出一个模板类,首先创建一个叫JokeModel的类继承与JSONModel类,添加id和text两个成员变量与JSON数据中的格式相对应。
  1. @interface JokeModel : JSONModel

  2. @property (assign, nonatomic) int id;
  3. @property (strong, nonatomic) NSString* text;

  4. @end
复制代码
    JSONModel会自动的将数字转换成相匹配的类型,下一步建立一个tag对象的类型用来保存JSON里tag字段的内容。创建一个TagModel类继承与JSONModel。添加id和tag成员,类型为NSString。
  1. @interface TagModel : JSONModel

  2. @property (strong, nonatomic) NSString* id;
  3. @property (strong, nonatomic) NSString* tag;

  4. @end
复制代码
    你已经设置好了id的类型为NSString。JSONModel本身已经知道如何将数字转换成字符。这样,你就只需要关心在应用里的数据类型而不用担心JSON数据是什么样的了。虽然TagModel类已经建立好,但需要告诉JSONModel在JokeModel类中的tags变量是一个TagModel类型。设置起来也不麻烦,在TagModel.h文件中添加一个空的TagModel协议。
  1. @protocol TagModel
  2. @end
复制代码
    然后在JokeModel.h中导入TagModel类
  1. #import "TagModel.h"
复制代码
    神奇的地方来了,在JokeModel里添加tags成员,类型为NSArray,包含两个协议。
  1. @property (strong, nonatomic) NSArray<TagModel, Optional>* tags;
复制代码
    1.TagModel是刚刚声明过的,它表示JokeModel里一个tags数组是TgaModel类,
    2.通过添加Optional,表示这个协议是一个可选的内容。
    这是一个很好的做法,这样的定义结构表示,如果一个JSON数据没有id或者text的内容,就会创建失败,tags数据可以为空。
   
    步骤3:显示设置

    先要对ViewController类做一些修改,打开ViewController.m,在顶部添加导入JokeModel类。
  1. #import "JokeModel.h"
复制代码
    在类中再添加两个成员:
    label用来显示笑话的内容
    jokes来存储笑话的所有数据
  1. @interface ViewController ()

  2. @property (strong, nonatomic) UILabel* label;
  3. @property (strong, nonatomic) NSArray* jokes;

  4. @end
复制代码
    下一步你需要将你获得的一条JSON的笑话数据,显示在屏幕上,修改viewDidLoad函数如下:
  1. - (void)viewDidLoad {
  2.     [super viewDidLoad];
  3.      
  4.     self.label = [[UILabel alloc] initWithFrame:self.view.bounds];
  5.     self.label.numberOfLines = 0;
  6.     self.label.textAlignment = NSTextAlignmentCenter;
  7.     self.label.alpha = 0;
  8.      
  9.     [self.view addSubview: self.label];
  10.      
  11.     [self fetchJokes];
  12. }
复制代码
    建立了一个UILabel控件在屏幕上,并将透明度设置为0。在第一条笑话数据还没有加载完之前它是隐藏的。在最后一行你看到的fetchJokes是从数据源读取JSON数据的请求,并把它们保存在界面里,接下来就说到如何实现fetchJokes。


步骤四:实现请求JSON数据和建立对象模型…………

步骤4:获得JSON数据与创建对象模板

    在这个例子里,通过NSURLSession类来获取远程的JSON数据。创建一个URL的请求,发送请求获取数据:

  1. - (void)fetchJokes {
  2.     NSURL* jokesUrl = [NSURL URLWithString:@"https://s3.amazonaws.com/com.tuts.mobile/jokes.json"];
  3.      
  4.     [[[NSURLSession sharedSession] dataTaskWithURL:jokesUrl completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
  5.         //handle data here
  6.     }] resume];
  7. }
复制代码
    dataTaskWithURL: completionHandler:创建了一个NSURLSessionDataTask传递URL的实例。并用resume来表示将这个数据任务添加到NSURLSession实例的任务队列中。下一步,初始化一个JokeMode实例,替换掉//handle data here成如下代码
  1. self.jokes = [JokeModel arrayOfModelsFromData:data error:nil];
复制代码
    arrayOfModelsFromData:error: l包含一个JSON响应的一个NSData对象,并返回一个模型数组,那么底层是如何工作的呢?
    1、JokeModel 将JSON数据转变一个JSON的对象数组;
    2、JokeModel遍历JSON对象数组的所有元素来创建出一个JokeModel实例;
    3、每个JokeModel实例根据JSON里对应的数据的值,来初始化JokeModel里的变量;
    4、如果JokeModel实例里包含tags键值,则用tags的数据来创建TagModel实例。
    如果你只需要创建一个模型实例,那么用initWithData和initWithString函数就能满足需求,在后面还会提到这两个函数。
    初始化笑话数组的任务完成后,就可以将第一条笑话显示在屏幕上:
  1. dispatch_async(dispatch_get_main_queue(), ^{
  2.     [self showNextJoke];
  3. });
复制代码


步骤5:显示笑话内容
  1. - (void)showNextJoke {
  2.     JokeModel* model = self.jokes[arc4random() % self.jokes.count];
  3.      
  4.     NSString* tags = model.tags?[model.tags componentsJoinedByString:@","]:@"no tags";
  5.     self.label.text = [NSString stringWithFormat:@"%i. %@\n\n%@", model.id, model.text, tags];
  6.      
  7.     [UIView animateWithDuration:1.0 animations:^{
  8.         self.label.alpha = 1.0;
  9.     } completion:^(BOOL finished) {
  10.         [self performSelector:@selector(hideJoke) withObject:nil afterDelay:5.0];
  11.     }];
  12. }
复制代码
    随机获取一条笑话数据把它存入model里,如果这条笑话包含tags的内容,就将tags的内容取出来,并用逗号分隔开。如果不含任何的tags内容,就设置tags的值为"no tags"。随后添加一个过渡效果,来刷新显示屏幕上id,text和tags的内容。过渡动画播放完后,等待5秒的时间后调用hideJoke,接着播放一个淡出消失的动画,这个动画播放完后,再次调用showNextJoke来显示下一条笑话。
  1. - (void)hideJoke {
  2.     [UIView animateWithDuration:1.0 animations:^{
  3.         self.label.alpha = 0.0;
  4.     } completion:^(BOOL finished) {
  5.         [self showNextJoke];
  6.     }];
  7. }
复制代码
    这样就建立了一个淡入淡出的显示循环。效果看起来还不错,来试试看吧。
jm1_6_jokevisible.png 
    然而,现在屏幕上看到的效果也许和你想象的不一样,TagMode对象显示出来的不是JSON的字符串内容,这是JSONModel库自带的一个功能,它会自动的创建一个对象的描述,包含了这个对象模型的属性和值,这样的做法能够帮助你去调试。下一个步骤告诉你如果不使用这种显示方式。


步骤6:自定义模板
    
    回看之前的步骤,现在要修改第一行的代码,继承JSONModel的模板和Objective-C的任何其他类一样,这意味着你可以重写JSONModel的一些默认方法,比如可以做这样的修改。
    打开TgaModel.m 覆盖默认的描述函数:
  1. - (NSString *)description {
  2.     return self.tag;
  3. }
复制代码


    现在调用到componentsJoineBySeparator的时候,将直接返回值,而不是像TagModel缺省的那样返回一些描述。再次运行应用,就能看到一个舒服的效果,运行一段时间,笑话逐条的显示出来。
jm1_7_jokevisibletags.png 


总结:


    看完教程,你已经基本入门JSONModel了。复习一下目前学习到了哪些内容:


    1、如何继承JSONModel类创建一个简单的模板类
    2、如何定义必要与可选属性
    3、如何定义嵌套类型


    这个简短的入门教程里,我只讲到了一些简单的功能,在这个系列的下一个部分中,您将了解更多关于数据转换、远程JSON接口的一些高级功能。

原文链接:http://code.tutsplus.com/tutorials/getting-started-with-jsonmodel--cms-19840

参考网址链接:http://bbs.9ria.com/thread-287213-1-1.html



  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值