iOS开发-JsonModel的学习及使用
IOS JsonModel的学习及使用
当我们从服务端获取到json数据后的时候,我们需要在界面上展示或者保存起来,下面来看下直接通过NSDictionary取出数据的情况。
NSDictionary直接取出数据的诟病。
NSString *name = [self.responseObj objectForKey:@"name"];NSString *gender = [self.responseObj objectForKey:@"gender"];NSString *sign = [self.responseObj objectForKey:@"sign"];NSString *avatar = [self.responseObj objectForKey:@"avatar"];NSString *phone = [self.responseObj objectForKey:@"phone"];NSString *token = [self.responseObj objectForKey:@"token"];
从以上的代码,我们能够看出,取出数据相当繁琐的。为了防止显示及出现crash等问题,还需要判断值的nil,null,类型等情况的出现。
所以我们需要使用到JSONModel。
简介JSONModel
JSONModel - 神奇的JSON数据建模框架 https://github.com/jsonmodel/jsonmodel
JSONModel可以快速创建智能数据模型。你可以在你的iOS,MacOS和watchOS和tvOS应用程序使用它。自动将JSON转成你的模型类,大大减少你需要编写的代码量。
见http://www.laileshuo.com/?p=669查看关于更改的详细信息。
(图片来源于网络)
JSONModel安装(Installation)
- 使用CocoaPods安装,在podfile,添加一下内容,之后使用pod update更新
pod 'JSONModel'
- 使用Carthage安装
github "jsonmodel/jsonmodel"
JSONModel使用手册(Manual)
- 下载JSONModel库
- 复制JSONModel子文件夹到您的Xcode项目
- 添加SystemConfiguration.framework库
JSONModel基础用法(Basic Usage)
假设你的JSON格式是这样的:
{ "id": 10, "country": "Germany", "dialCode": 49, "isInEurope": true }
- 创建一个JSONModel的子类
- 在.h头文件中声明一些以json的key命名的属性
@interface CountryModel : JSONModel@property (nonatomic) NSInteger id;@property (nonatomic) NSString *country;@property (nonatomic) NSString *dialCode;@property (nonatomic) BOOL isInEurope;@end
之后我们没有必要在.m文件中多做什么特殊的处理。
初始化数据模型:
NSError *error;CountryModel *country = [[CountryModel alloc] initWithString:myJson error:&error];
如果验证JSON通过的话,将会通过json中的key的value值为CountryModel的id,country,dialCode,isInEurope的属性赋值。并且自动匹配相遇的类型。
实例
自动根据名称映射
{"id": 123,"name": "Product name","price": 12.95}
@interface ProductModel : JSONModel@property (nonatomic) NSInteger id;@property (nonatomic) NSString *name;@property (nonatomic) float price;@end
模型嵌套 (模型包含其他模型)
{"orderId": 104,"totalPrice": 13.45,"product": {"id": 123,"name": "Product name","price": 12.95}}
@interface ProductModel : JSONModel@property (nonatomic) NSInteger id;@property (nonatomic) NSString *name;@property (nonatomic) float price;@end@interface OrderModel : JSONModel@property (nonatomic) NSInteger orderId;@property (nonatomic) float totalPrice;@property (nonatomic) ProductModel *product;@end
模型集合collections
{"orderId": 104,"totalPrice": 103.45,"products": [{"id": 123,"name": "Product #1","price": 12.95},{"id": 137,"name": "Product #2","price": 82.95}]}
@protocol ProductModel;@interface ProductModel : JSONModel@property (nonatomic) NSInteger id;@property (nonatomic) NSString *name;@property (nonatomic) float price;@end@interface OrderModel : JSONModel@property (nonatomic) NSInteger orderId;@property (nonatomic) float totalPrice;@property (nonatomic) NSArray <ProductModel> *products;@end
注:NSArray的后尖括号包含的协议。这是不一样的目标C泛型系统。它们不是相互排斥的,而是为JSONModel工作,该协议必须到位。
嵌套键映射
{"orderId": 104,"orderDetails": [{"name": "Product #1","price": {"usd": 12.95}}]}
@interface OrderModel : JSONModel
@property (nonatomic) NSInteger id;
@property (nonatomic) NSString *productName;
@property (nonatomic) float price;
@end@implementation OrderModel+ (JSONKeyMapper *)keyMapper
{return [[JSONKeyMapper alloc] initWithModelToJSONDictionary:@{@"id": @"orderId",@"productName": @"orderDetails.name",@"price": @"orderDetails.price.usd"}];
}@end
自动映射到snake_case
{"order_id": 104,"order_product": "Product #1","order_price": 12.95
}
@interface OrderModel : JSONModel
@property (nonatomic) NSInteger orderId;
@property (nonatomic) NSString *orderProduct;
@property (nonatomic) float orderPrice;
@end@implementation OrderModel+ (JSONKeyMapper *)keyMapper
{return [JSONKeyMapper mapperForSnakeCase];
}@end
可选属性Optional (就是说这个属性可以为null或者为空)
{"id": 123,"name": null,"price": 12.95
}
@interface ProductModel : JSONModel
@property (nonatomic) NSInteger id;
@property (nonatomic) NSString <Optional> *name;
@property (nonatomic) float price;
@property (nonatomic) NSNumber <Optional> *uuid;
@end
忽略属性 Ignored (就是JSONModel完全忽略这个属性)
{"id": 123,"name": null
}
@interface ProductModel : JSONModel
@property (nonatomic) NSInteger id;
@property (nonatomic) NSString <Ignore> *customProperty;
@end
设置标量类型可选optional
{"id": null
}
@interface ProductModel : JSONModel
@property (nonatomic) NSInteger id;
@end@implementation ProductModel+ (BOOL)propertyIsOptional:(NSString *)propertyName
{if ([propertyName isEqualToString:@"id"])return YES;return NO;
}@end
将model转成json
ProductModel *pm = [ProductModel new];
pm.name = @"Some Name";// convert to dictionary
NSDictionary *dict = [pm toDictionary];// convert to json
NSString *string = [pm toJSONString];
特定类型数据转换
@interface JSONValueTransformer (CustomNSDate)
@end@implementation JSONValueTransformer (CustomTransformer)- (NSDate *)NSDateFromNSString:(NSString *)string
{NSDateFormatter *formatter = [NSDateFormatter new];formatter.dateFormat = APIDateFormat;return [formatter dateFromString:string];
}- (NSString *)JSONObjectFromNSDate:(NSDate *)date
{NSDateFormatter *formatter = [NSDateFormatter new];formatter.dateFormat = APIDateFormat;return [formatter stringFromDate:date];
}@end
自定义 getters/setters
@interface ProductModel : JSONModel
@property (nonatomic) NSInteger id;
@property (nonatomic) NSString *name;
@property (nonatomic) float price;
@property (nonatomic) NSLocale *locale;
@end@implementation ProductModel- (void)setLocaleWithNSString:(NSString *)string
{self.locale = [NSLocale localeWithLocaleIdentifier:string];
}- (void)setLocaleWithNSDictionary:(NSDictionary *)dictionary
{self.locale = [NSLocale localeWithLocaleIdentifier:dictionary[@"identifier"]];
}- (NSString *)JSONObjectForLocale
{return self.locale.localeIdentifier;
}@end
自定义验证JSON
@interface ProductModel : JSONModel
@property (nonatomic) NSInteger id;
@property (nonatomic) NSString *name;
@property (nonatomic) float price;
@property (nonatomic) NSLocale *locale;
@property (nonatomic) NSNumber <Ignore> *minNameLength;
@end@implementation ProductModel- (BOOL)validate:(NSError **)error
{if (![super validate:error])return NO;if (self.name.length < self.minNameLength.integerValue){*error = [NSError errorWithDomain:@"me.mycompany.com" code:1 userInfo:nil];return NO;}return YES;
}@end
如果您需要查看详情JSONModel的使用请访问https://github.com/jsonmodel/jsonmodel ,以便下载最新代码进行研究使用。
学习记录,每天不停进步。
相关文章:
iOS开发-JsonModel的学习及使用
IOS JsonModel的学习及使用 当我们从服务端获取到json数据后的时候,我们需要在界面上展示或者保存起来,下面来看下直接通过NSDictionary取出数据的情况。 NSDictionary直接取出数据的诟病。 NSString *name [self.responseObj objectForKey:"nam…...
jquery 遍历所有元素
要遍历所有元素,您可以使用 jQuery 的 .each() 方法。以下是使用 .each() 方法来遍历所有元素的示例代码: $(selector).each(function() {// 在这里编写处理每个元素的代码// 使用 $(this) 来访问当前迭代的元素 });在上面的代码中,您需要将…...
Tik Tok跨境电商新风向,跨境卖家该如何布局?
TikTok作为优质的中国出海企业,近年来在电商业务上的布局也越来越广泛,除了之前的内容电商,TikTok Shop也上线了商城业务,补全了“人找货”的场景,为卖家增加了在直播、短视频之外的新流量来源。 TikTok美国小店现状 …...
OR36 链表的回文结构 题解
题目描述:链表的回文结构_牛客题霸_牛客网 (nowcoder.com) 对于一个链表,请设计一个时间复杂度为O(n),额外空间复杂度为O(1)的算法,判断其是否为回文结构。 给定一个链表的头指针A,请返回一个bool值,代表其是否为回文结…...
“去没有天花板的地方” | 小红书用户情绪数据
最近,话题#人就要待在没有天花板的地方#社媒讨论度居高不下,小红书相关话题近90天互动量超百万。 生活的无常之外,越来越多人渴望与大自然更深层次的链接,以此寻找情绪的不同出口。或许,剖析这些情绪的生成机理&#x…...
Java文件操作(遍历目录中的文件,找到并删除有指定关键字的文件)
对于通过java对文件继续读取和写入的操作推荐看读取文件和写入文件操作 题目 扫描指定目录中的文件,并找到名称中包含指定字符的所有普通文件(不包括目录),并后续询问用户是否要删除该文件 题目分析 实际上题目就要求我们对一个…...
MySQL单表查询
单表查询 素材: 表名:worker-- 表中字段均为中文,比如 部门号 工资 职工号 参加工作 等 CREATE TABLE worker ( 部门号 int(11) NOT NULL, 职工号 int(11) NOT NULL, 工作时间 date NOT NULL, 工资 float(8,2) NOT NULL, 政治面貌 varch…...
苹果正在测试新款Mac mini:搭载M3芯片 配备24GB大内存
据悉苹果目前正在测试新的Mac机型,亮点是采用最新的M3芯片。 据报道,首款搭载M3芯片的设备应该是13英寸的MacBook Pro和重新设计的MacBook Air,Mac mini机型并不在名单上。 M3和M2同样拥有最多8个核心,分别为4个性能核和4个能效核…...
redis的缓存更新策略以及如何保证redis与数据库的数据一致性
redis的缓存更新策略有这么几种: 1、由应用直接和redis以及数据库相连接: 查询数据时,应用去redis中查询,查不到的话再由应用去数据库中查询,并将查询结果放在redis; 更新数据时ÿ…...
k8s--使用cornJob定时执行sql文件
CronJob apiVersion: batch/v1beta1 kind: CronJob metadata:name: hello spec:schedule: "0 * * * *"jobTemplate:spec:template:spec:containers:- name: postgres-alpineimage: xxxximagePullPolicy: IfNotPresentcommand:- psql- -h- 数据库服务地址- -d- 数据库…...
Qt事件过滤器
1 介绍 事件过滤器是一种机制,当某个QObject没有所需要的事件功能时,可将其委托给其它QObject,通过eventFilter成员函数来过滤实现功能。 2 主要构成 委托: ui->QObject1->installEventFilter(QObject2); eventFilter声明 …...
Java基础集合框架学习(上)
文章目录 初识基础框架为什么使用集合框架集合框架的继承关系ArrayList入门案例单元测试和增删改查单元测试的注意事项LinkedList入门案例ArrayList底层是数组LinkedList底层是链表ArrayList和LinkedList选型ArrayList存放DOG对象 初识基础框架 Java基础集合框架是Java编程语言…...
北京多铁克FPGA笔试题目
1、使用D触发器来实现二分频 2、序列检测器,检测101,输出1,其余情况输出0 module Detect_101(input clk,input rst_n,input data, //输入的序列output reg flag_101 //检测到101序列的输出标志 );parameter S0 2d0;S1 2d1;S2 2d2;S4 …...
从初学者的角度来理解指针常量和常量指针
重新理解指针常量,常量指针 应用 我先提一个问题:知道指针常量,常量指针存在的作用是什么吗? 先了解它们存在的作用再去理解它们,或许更轻松些。 比如配置文件读取:在许多工程中,配置文件用于…...
C# OpenCvSharp 去水印 图像修复
效果 项目 VS2022.net4.8OpenCvSharp4 代码 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.IO; using System.Linq; using System.Security.Cryptography; using System.Text; usi…...
考研算法第40天:众数 【模拟,简单题】
题目 本题收获 又是一道比较简单的模拟题,就不说解题思路了,说一下中间遇到的问题吧,就是说cin输入它是碰到空格就停止输入的,详细的看下面这篇博客对于cin提取输入流遇到空格的问题_while(cin) 空格_就是那个党伟的博客-CSDN博…...
MySQL:内置函数、复合查询和内外连接
内置函数 select 函数; 日期函数 字符串函数 数学函数 其它函数 复合查询(多表查询) 实际开发中往往数据来自不同的表,所以需要多表查询。本节我们用一个简单的公司管理系统,有三张 表EMP,DEPT,SALGRADE来演示如何进行多表查询…...
【HTML】label 标签
在HTML中,<label> 标签用于为表单元素创建标签文本或标题。它可以与输入字段(如文本框、单选按钮、复选框等)和其他表单元素关联起来,以提高可用性和可访问性。 <label> 元素有两种常见的用法: 包裹方式…...
python视频流截图(按帧数)
一、安装opencv计算机视觉库 pip install opencv-python二、视频流截图 1、读取视频文件,获取视频帧数 import cv2 # 视频位置 video_path path_file_name # 读取视频 cap cv2.VideoCapture(video_path) # 获取视频总帧数 frame_count cap.get(cv2.CAP_PROP_F…...
MongoDB SQL
Microsoft Windows [版本 6.1.7601] 版权所有 (c) 2009 Microsoft Corporation。保留所有权利。C:\Users\Administrator>cd C:\MongoDB\Server\3.4\binC:\MongoDB\Server\3.4\bin> C:\MongoDB\Server\3.4\bin> C:\MongoDB\Server\3.4\bin>net start MongoDB 请求的…...
SpringBoot-17-MyBatis动态SQL标签之常用标签
文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...
Chapter03-Authentication vulnerabilities
文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...
mongodb源码分析session执行handleRequest命令find过程
mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程,并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令,把数据流转换成Message,状态转变流程是:State::Created 》 St…...
Frozen-Flask :将 Flask 应用“冻结”为静态文件
Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是:将一个 Flask Web 应用生成成纯静态 HTML 文件,从而可以部署到静态网站托管服务上,如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...
页面渲染流程与性能优化
页面渲染流程与性能优化详解(完整版) 一、现代浏览器渲染流程(详细说明) 1. 构建DOM树 浏览器接收到HTML文档后,会逐步解析并构建DOM(Document Object Model)树。具体过程如下: (…...
Nuxt.js 中的路由配置详解
Nuxt.js 通过其内置的路由系统简化了应用的路由配置,使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...
Nginx server_name 配置说明
Nginx 是一个高性能的反向代理和负载均衡服务器,其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机(Virtual Host)。 1. 简介 Nginx 使用 server_name 指令来确定…...
python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)
更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...
CMake 从 GitHub 下载第三方库并使用
有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...
Unit 1 深度强化学习简介
Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库,例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体,比如 SnowballFight、Huggy the Do…...
