JSONModal 的使用

原创 2015年07月08日 22:25:07

前言

接触 ios 开发有4个多月了,在这期间,做了一个小型的项目,也参与到公司项目的开发之中,也算是正式地成为一个 ios 开发者了。今天,偶然间接触到了 JSONModal 这个开源库之后,心里的感受只能用“相见恨晚”来诠释。 JSONModal 让我们对服务器 JSON 数据的解析变得如此简单,优雅。我们只需向服务器请求数据,然后几乎不需要做什么工作就可以得到一个我们想要的 modal,这是一件多么幸福的事情啊!本文对JSONModal 的使用方法的介绍主要参考 JSONModal 库的 markdown 文件。


简介

JSONModel 是一个能够让你根据获取到的服务器数据快速而智能地建立出一个数据模型(modal)的开源库。你可以在 ios 和 OSX 程序中使用该库。
JSONModel 能够自动地将你获取到 json 数据映射到你的 modal 中,从而减少你对这些数据进行解析的繁杂而不优雅的代码(表示没用该库之前一个对JSON数据一个一个进行解析的感觉好痛苦啊)。

JSONModel

添加 JSONModal 到你的项目中

环境要求

  • ARC内存管理
  • iOS 5.0+ / OSX 10.7+
  • SystemConfiguration.framework

获取 JSONModal

两种方法:

直接使用源文件

  1. 到 github 直接将 JSONModal 整个源文件下载下来
  2. 添加 JSONModel 整个文件夹到你的项目当中
  3. 添加依赖库SystemConfiguration.framework

利用Cocoa pods

在 Podfile 中添加如下语句:

pod 'JSONModel'

关于 Cocoa pods 的使用请自行搜索相关的资料


基本用法

假设你获取到的 JSON 数据如下所示:

    {"id":"10", "country":"Germany", "dialCode": 49, "isInEurope":true}
  • 创建一个类作为你的 modal 类,并且使得该类继承 JSONModel 类
  • 在该类的头文件中声明各个属性,属性的名称应该与 json 数据
#import "JSONModel.h"

@interface CountryModel : JSONModel

@property (assign, nonatomic) int id;
@property (strong, nonatomic) NSString* country;
@property (strong, nonatomic) NSString* dialCode;
@property (assign, nonatomic) BOOL isInEurope;

@end

在 .m 文件中无需写任何的代码

  • 初始化数据
#import "CountryModel.h"

NSString* json = (fetch here JSON from Internet) ... 

NSError* err = nil;

CountryModel* country = [[CountryModel alloc] initWithString:json error:&err];

细心的你可能会发现,我们在 CountryModel 类中所声明的属性的类型与 json 数据中相关的类型是不同的,这样真的可以么?是的, JSONModal 就是这样智能,你要做的只是在你的 CountryModel 类中声明你想要的属性类型就可以了。
以下列出各种情况下的一些示例代码


示例代码

1. 简单的映射(获取到的数据是一个简单的字典)

{
  "id": "123",
  "name": "Product name",
  "price": 12.95
}
@interface ProductModel : JSONModel
@property (assign, nonatomic) int id;
@property (strong, nonatomic) NSString* name;
@property (assign, nonatomic) float price;
@end

@implementation ProductModel
@end

2. model 之中嵌套了 model 的情况

{
  "order_id": 104,
  "total_price": 13.45,
  "product" : {
    "id": "123",
    "name": "Product name",
    "price": 12.95
  }
}
@interface OrderModel : JSONModel
@property (assign, nonatomic) int order_id;
@property (assign, nonatomic) float total_price;
@property (strong, nonatomic) ProductModel* product;//直接声明一个product 所对应的对象即可
@end

@implementation OrderModel
@end

3. 内嵌model并且内部model拥有多个元素(数组)

{
  "order_id": 104,
  "total_price": 103.45,
  "products" : [
    {
      "id": "123",
      "name": "Product #1",
      "price": 12.95
    },
    {
      "id": "137",
      "name": "Product #2",
      "price": 82.95
    }
  ]
}
@protocol ProductModel
@end

@interface ProductModel : JSONModel
@property (assign, nonatomic) int id;
@property (strong, nonatomic) NSString* name;
@property (assign, nonatomic) float price;
@end

@implementation ProductModel
@end

@interface OrderModel : JSONModel
@property (assign, nonatomic) int order_id;
@property (assign, nonatomic) float total_price;
@property (strong, nonatomic) NSArray<ProductModel>* products;
@end

@implementation OrderModel
@end

4. model 多层嵌套(3 层以上)

当modal的嵌套在 3 层以上的时候,就需要在 keyMapper 函数中对modal的属性和 json的键值之间做一个映射。

{
  "order_id": 104,
  "order_details" : [
    {
      "name": "Product#1",
      "price": {
        "usd": 12.95
      }
    }
  ]
}
@interface OrderModel : JSONModel
@property (assign, nonatomic) int id;
@property (assign, nonatomic) float price;
@property (strong, nonatomic) NSString* productName;
@end

@implementation OrderModel

+(JSONKeyMapper*)keyMapper
{
  return [[JSONKeyMapper alloc] initWithDictionary:@{
    @"order_id": @"id",
    @"order_details.name": @"productName",
    @"order_details.price.usd": @"price"
  }];
}

@end

当你的程序中有多个 modal 具有相同的属性名,并且需要映射层别的名字的时候,可以使用 JSONModel 的全局映射,这样,整个 App 中所有的 modal 中相应的字段都会映射到指定的名字。

[JSONModel setGlobalKeyMapper:[
    [JSONKeyMapper alloc] initWithDictionary:@{
      @"item_id":@"ID",
      @"item.name": @"itemName"
   }]
];

5. 下滑线的命名映射到驼峰式的命名

{
  "order_id": 104,
  "order_product" : @"Product#1",
  "order_price" : 12.95
}
@interface OrderModel : JSONModel

@property (assign, nonatomic) int orderId;
@property (assign, nonatomic) float orderPrice;
@property (strong, nonatomic) NSString* orderProduct;

@end

@implementation OrderModel

+(JSONKeyMapper*)keyMapper
{
  return [JSONKeyMapper mapperFromUnderscoreCaseToCamelCase];
}

@end

6. 可选属性

在实际的开发过程中,经常遇到这样的情况,从服务器获取到 json 数据中有某个数据的值为 null,或者获取到的 json 数据中缺少 model 中的某个或几个属性, 在这两种情况下, JSONModal 都会发生解析错误。
为了避免这种错误,需要在 model 具体的字段上将属性声明为可选属性。

{
  "id": "123",
  "name": null,
  "price": 12.95
}

@interface ProductModel : JSONModel
@property (assign, nonatomic) int id;
@property (strong, nonatomic) NSString<Optional>* name;
@property (assign, nonatomic) float price;
@property (strong, nonatomic) NSNumber<Optional>* uuid;
@end

@implementation ProductModel
@end

7. 忽略相关属性

在开发的过程中,有时我们需要 JSONModal 忽略我们自定义的 model 中得某些属性,这时需要将相关的属性声明为 Ignore

{
  "id": "123",
  "name": null
}
@interface ProductModel : JSONModel
@property (assign, nonatomic) int id;
@property (strong, nonatomic) NSString<Ignore>* customProperty;
@end

@implementation ProductModel
@end

8. 设置 model 的所有的属性为可选的属性

JSONModel 提供了一种设置 model 中所有的属性全部为可选的方法,具体如下:

@implementation ProductModel
+(BOOL)propertyIsOptional:(NSString*)propertyName
{
  return YES;
}
@end

9. 惰性解析转化

为了提高程序的效率,我们在程序中经常会采用“懒加载”的方法,即使用一个对象的时候,不要创建该对象,而是等到要用到该对象的时候才对对象进行创建。这里用到的思路是一样的,即等到要用到 model 中某个属性的时候,才对 json 数据进行解析并映射到 model 的属性中以供使用。

{
  "order_id": 104,
  "total_price": 103.45,
  "products" : [
    {
      "id": "123",
      "name": "Product #1",
      "price": 12.95
    },
    {
      "id": "137",
      "name": "Product #2",
      "price": 82.95
    }
  ]
}
@protocol ProductModel
@end

@interface ProductModel : JSONModel
@property (assign, nonatomic) int id;
@property (strong, nonatomic) NSString* name;
@property (assign, nonatomic) float price;
@end

@implementation ProductModel
@end

@interface OrderModel : JSONModel
@property (assign, nonatomic) int order_id;
@property (assign, nonatomic) float total_price;
@property (strong, nonatomic) NSArray<ProductModel, ConvertOnDemand>* products;//添加ConvertOnDemand
@end

@implementation OrderModel
@end

写在最后

谢谢您的阅读,如果有什么意见和建议,欢迎交流!

版权声明:本文为博主原创文章,未经博主允许不得转载。

bootstrap的modal-remote两种加载方式【强化】

bootstrap的modal-remote加载页面$(function(){})方法执行异常解决办法

定时器的使用

  • 2017年12月13日 09:44
  • 170KB
  • 下载

Idea环境下使用JFinal开发Web项目入门详解(图文版)

最近看到网上有人推荐使用JFinal(官网:http://www.jfinal.com/)开发WEB + ORM项目,自己于是到官网学习JFinal,官方文档提供了使用eclipse开发Jfinal项...

MFC Flash的简单使用

  • 2017年12月12日 13:18
  • 93.56MB
  • 下载

Android高德地图使用

在Swift基础 - - 高德地图实践(一)中使用swift来使用高德地图,这里使用Android实践高德地图包含定位,移动地图动画,获取网络数据,marker标记以及点击,Infowindow自定义...

CAM350使用教程

  • 2017年12月11日 16:26
  • 1.38MB
  • 下载

WebService与SQL的结合使用

  • 2017年12月11日 14:42
  • 33.97MB
  • 下载

安装使用Arch Linux(上篇)

安装使用Arch Linux(上篇)目录安装使用Arch Linux上篇 目录 安装前 下载Arch Linux镜像 制作BIOS和UEFI下的usb启动盘 从启动盘启动Arch Linux 验证bo...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:JSONModal 的使用
举报原因:
原因补充:

(最多只允许输入30个字)