iOS中JSONModel的使用

 

流弊的JSON数据模型框架

https://github.com/jsonmodel/jsonmodel

版本 1.3.0


如果你喜欢JSONModel,并且使用了它,请你:

  • star一下

  • 给我一些反馈. 多谢!


JSONModel for iOS and OSX

JSONModel 是一个能够快速巧妙的创建数据模型的库. 你可以在 iOS or OSX APP中使用它.

JSONModel 自动检查JOSN模型和结构体, 彻底的减少你的代码量.


添加JSONModel到你的项目中

要求

  • 支持持ARC; iOS 5.0+ / OSX 10.7+
  • SystemConfiguration.framework

as: 1) 源文件

1.下载JSONModel.zip文件
2.将它拷贝到你的项目中
3.导入SystemConfiguration.framework框架

or 2)使用 CocoaPods

pod 'JSONModel'

如果你想关于CocoaPods了解更多,请参考这个简单的教程.

or 3) 使用 Carthage

在你的项目的Cartfile添加JSONModel:

github "jsonmodel/jsonmodel"

文档

你可以查看在线阅读文档: http://cocoadocs.org/docsets/JSONModel


基本使用

涉想你的JSON数据像这样:

{ "id": "10", "country": "Germany", "dialCode": 49, "isInEurope": true }
  • 为你的数据模型创建一个Objective-C的类,继承自JSONModel.
  • 将JSON中的keys在.h文件中声明为属性:
#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文件中不需要做任何事情.

  • 用数据初始化你的model:
#import "CountryModel.h"
... NSString* json = (fetch here JSON from Internet) ...
NSError* err = nil;
CountryModel* country = [[CountryModel alloc] initWithString:json error:&err];

如果传过来的JSON合法,你所定义的所有的属性都会与该JSON的值想对应,甚至JSONModel会尝试去转换数据为你期望的类型,如上所示:

  • 转换id,从字符串转换为int
  • 只需要拷贝一下country的值
  • 转换diaCode,从number转换为字符串
  • 最后一个是将isInEurope转换为BOOL属性

所以,你所需要做的就是将你的属性定义为期望的类型.


在线教程

官方网站: http://www.jsonmodel.com

在线文档: http://jsonmodel.com/docs/

傻瓜教程:


举个栗子

命名自动匹配

{
"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

模型嵌套 (模型包含其他模型)

{
"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;
@end @implementation OrderModel
@end

模型集合

{
"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

注意: 尖括号后 NSArray 包含一个协议. 这跟Objective-C原生的泛型不是一个概念. 他们不会冲突, 但对于JSONModel来说,协议必须在一个地方声明.

key映射

{
"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

设置全局键映射(应用于所有model)

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

设置下划线自动转驼峰

{
"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

可选属性 (就是说这个属性可以为null或者为空)

{
"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

忽略属性 (就是完全忽略这个属性)

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

设置所有的属性为可选(所有属性值可以为空)

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

使用JSONModel自带的 HTTP 请求

//add extra headers
[[JSONHTTPClient requestHeaders] setValue:@"MySecret" forKey:@"AuthorizationToken"]; //make post, get requests
[JSONHTTPClient postJSONFromURLWithString:@"http://mydomain.com/api"
params:@{@"postParam1":@"value1"}
completion:^(id json, JSONModelError *err) { //check err, process json ... }];

将model转化为字典或者json格式的字符串

ProductModel* pm = [[ProductModel alloc] initWithString:jsonString error:nil];
pm.name = @"Changed Name"; //convert to dictionary
NSDictionary* dict = [pm toDictionary]; //convert to text
NSString* string = [pm toJSONString];

自定义数据的转换

@implementation JSONValueTransformer (CustomTransformer)

- (NSDate *)NSDateFromNSString:(NSString*)string {
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:APIDateFormat];
return [formatter dateFromString:string];
} - (NSString *)JSONObjectFromNSDate:(NSDate *)date {
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:APIDateFormat];
return [formatter stringFromDate:date];
} @end

自定义处理指定的属性

@interface ProductModel : JSONModel
@property (assign, nonatomic) int id;
@property (strong, nonatomic) NSString* name;
@property (assign, nonatomic) float price;
@property (strong, nonatomic) NSLocale *locale;
@end @implementation ProductModel // Convert and assign the locale property
- (void)setLocaleWithNSString:(NSString*)string {
self.locale = [NSLocale localeWithLocaleIdentifier:string];
} - (NSString *)JSONObjectForLocale {
return self.locale.localeIdentifier;
} @end

自定义JSON校验

@interface ProductModel : JSONModel
@property (assign, nonatomic) int id;
@property (strong, nonatomic) NSString* name;
@property (assign, nonatomic) float price;
@property (strong, nonatomic) NSLocale *locale;
@property (strong, nonatomic) NSNumber <Ignore> *minNameLength;
@end @implementation ProductModel - (BOOL)validate:(NSError *__autoreleasing *)error {
BOOL valid = [super validate:error]; if (self.name.length < self.minNameLength.integerValue) {
*error = [NSError errorWithDomain:@"me.mycompany.com" code:1 userInfo:nil];
valid = NO;
} return valid;
} @end
  • 错误处理
  • 自定义数据校验
  • 自动比较和相等判断
  • 更多.

Misc

作者: Marin Todorov

参与者: Christian Hoffmann, Mark Joslin, Julien Vignali, Symvaro GmbH, BB9z.
任何人都可以 pull requests.

更新log : https://github.com/jsonmodel/jsonmodel/blob/master/CHANGELOG.md

Utility to generate JSONModel classes from JSON data:https://github.com/dofork/json2object


许可

This code is distributed under the terms and conditions of the MIT license.


参考指南

NB! 如果你解决了你发现的某个BUG, 请添加单元测试,这样以便我在合并之前复现这个BUG.


使用问题汇总

1、1.4.0版本的JSONKeyMapper

如果需要替换服务端返回来的key,需要按照下面的结构@{@"你的key":@"接口返回的key"},并且请使用initWithModelToJSONDictionary这个方法。

+ (JSONKeyMapper *)keyMapper {
return [[JSONKeyMapper alloc] initWithModelToJSONDictionary:
@{
@"isChecked":@"ischecked",
@"tagId":@"tagid",
@"tagName":@"tagname",
@"tagValue":@"tagvalue"
}];
}
2、模型包含模型时的使用, 被包含的模型需要声明protocol

eg:KSAlreadyBuyListModel 包含一个属性KSAlreadyBuyModel, 我们需要将KSAlreadyBuyModel声明protocol,不然会解析失败。

@class StoryModel, AblumModel;

@protocol KSAlreadyBuyModel <NSObject>
@end @interface KSAlreadyBuyModel : KSBaseModel @property (nonatomic, strong) StoryModel *storyModel;
@property (nonatomic, strong) AblumModel *ablumModel; @end @protocol KSAlreadyBuyListModel <NSObject>
@end @interface KSAlreadyBuyListModel : KSBaseModel @property (nonatomic, copy) NSString *contentid;
@property (nonatomic, copy) NSString *contenttype;
@property (nonatomic, copy) NSString *iconurl;
@property (nonatomic, copy) NSString *orderno;
@property (nonatomic, copy) NSString *productid;
@property (nonatomic, copy) NSString *productname;
@property (nonatomic, copy) NSString *realityprice;
@property (nonatomic, strong) KSAlreadyBuyModel *param; @end

iOS中JSONModel的使用的更多相关文章

  1. iOS 中JSONModel的使用

    基本使用 涉想你的JSON数据像这样: { "id": "10", "country": "Germany", &quo ...

  2. iOS 中有用的开源库

    youtube下载神器:https://github.com/rg3/youtube-dl vim插件:https://github.com/Valloric/YouCompleteMe vim插件配 ...

  3. iOS 中 常用的第三方库

    现在对于我们 iOS 开发来说,基本上说不可能不使用第三方轮子啦,毕竟没那么多时间,而且自己造的轮子往往想着成为上图中的最后一个,结果却成了上图中第二个或第一个啦,当然大公司另当别论.下面我从之前用过 ...

  4. iOS中支付宝集成

    iOS中支付宝集成 如今各种的App中都使用了三方支付的功能,现在将我在使用支付宝支付集成过程的心得分享一下,希望对大家都能有所帮助 要集成一个支付宝支付过程的环境,大致需要: 1>公司:先与支 ...

  5. iOS中数据库应用基础

    iOS 数据库入门 一.数据库简介 1.什么是数据库? 数据库(Database) 是按照数据结构来组织,存储和管理数据的仓库 数据库可以分为2大种类 关系型数据库(主流) PC端 Oracle My ...

  6. 正则表达式在iOS中的运用

    1.什么是正则表达式 正则表达式,又称正规表示法,是对字符串操作的一种逻辑公式.正则表达式可以检测给定的字符串是否符合我们定义的逻辑,也可以从字符串中获取我们想要的特定部分.它可以迅速地用极简单的方式 ...

  7. iOS 中的 HotFix 方案总结详解

    相信HotFix大家应该都很熟悉了,今天主要对于最近调研的一些方案做一些总结.iOS中的HotFix方案大致可以分为四种: WaxPatch(Alibaba) Dynamic Framework(Ap ...

  8. iOS中使用正则

    一.什么是正则表达式 正则表达式,又称正规表示法,是对字符串操作的一种逻辑公式.正则表达式可以检测给定的字符串是否符合我们定义的逻辑,也可以从字符串中获取我们想要的特定部分.它可以迅速地用极简单的方式 ...

  9. IOS中div contenteditable=true无法输入

    在IOS中<div contenteditable="true"></div>中点击时可以弹出键盘但是无法输入.加一个样式-webkit-user-sele ...

随机推荐

  1. hdu 4028 2011上海赛区网络赛H dp+map离散

    一开始用搜索直接超时,看题解会的 #include<iostream> #include<cstdio> #include<map> #include<cst ...

  2. 使用AStyle进行代码格式化

    转自:http://www.cnblogs.com/JerryTian/archive/2012/09/20/AStyle.html 在日常的编码当中,大家经常要遵照一些设计规范,如命名规则.代码格式 ...

  3. mybatis 中#和$的区别

    #{…}是一个参数标记,将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号.如:order by #user_id#,如果传入的值是1,那么解析成sql时的值为order by " ...

  4. 2016北京网络赛 hihocoder 1391 Countries 树状数组

    Countries   描述 There are two antagonistic countries, country A and country B. They are in a war, and ...

  5. CSS实现打字效果

    .print{ width:250px; white-space:nowrap; overflow:hidden; -webkit-animation: dy 3s steps(60, end) in ...

  6. Linux---从start_kernel到init进程启动

    “平安的祝福 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 ” ini ...

  7. LoadRunner关联函数的脚本实例--如何操作关联参数

    LoadRunner关联函数的脚本实例--如何操作关联参数 这几天一直在学习LoadRunner的VuGen编程,今天想对关联函数web_reg_save_param做详细的试验和研究: ~f6p q ...

  8. windows进程中的内存结构[转载]

    在阅读本文之前,如果你连堆栈是什么多不知道的话,请先阅读文章后面的基础知识. 接触过编程的人都知道,高级语言都能通过变量名来访问内存中的数据.那么这些变量在内存中是如何存放的呢?程序又是如何使用这些变 ...

  9. java.lang.instrument使用

    Java在1.5引入java.lang.instrument,你可以由此实现一个Javaagent,通过此agent来修改类的字节码即改变一个类. 程序启动之时启动代理(pre-main) 通过jav ...

  10. tomcat 部署spring工程乱码解决方案

    tomcat的server.xml文件,Connector标签增加useBodyEncodingForURI="true"属性 web.xml如下配置 <filter> ...