iOS开发-JsonModel的学习及使用

news2024/11/15 23:48:56

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查看关于更改的详细信息。

alt text (图片来源于网络)

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 ,以便下载最新代码进行研究使用。

学习记录,每天不停进步。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/855529.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Vue3弹出确认(Popconfirm)

效果如下图&#xff1a;在线预览 APIs 参数说明类型默认值必传title确认框的标题string | slot‘’falsedescription确认框的内容描述string | slot‘’falsecontent展示的文本string | slot‘’falseicon自定义弹出确认框 Icon 图标string | slot‘’falsemaxWidth弹出确认框…

《合成孔径雷达成像算法与实现》Figure3.8

与图3.7的代码区别只在于原始信号的表达式对了一个时间偏移 代码复现如下&#xff1a; clc clear all close all%参数设置 TBP 100; %时间带宽积 T 10e-6; %脉冲持续时间 tc …

SEED-Bench: Benchmarking Multimodal LLMs with Generative Comprehension

本文是LLM相关的文章&#xff0c;针对《SEED-Bench: Benchmarking Multimodal LLMs with Generative Comprehension》的翻译。 SEED-基准&#xff1a;用生成理解对多模式LLM进行基准测试 摘要1 引言2 相关工作3 SEED-Bench 摘要 基于强大的大型语言模型&#xff08;LLM&#…

【SpringBoot框架篇】33.优雅集成i18n实现国际化信息返回

文章目录 1.简介2.MessageSource配置和工具类封装2.1.配置MessageSource相关配置2.2.配置工具类2.3.测试返回国际级文本信息 3.不优雅的web调用示例(看看就行&#xff0c;别用)4.优雅使用示例4.1.错误响应消息枚举类4.2.ThreadLocal工具类配置4.2.1.ThreadLocal工具类数据封装4…

不再限制CPU,这才是Win11完全体的样子嘛

从 Win11 刚问世时&#xff0c;微软就宣称将给其许多 Win10没有也不会支持的新功能。 其中 Android 子系统的支持算得上是最期待&#xff0c;但结果难免有些失望的部分。 先不说使用怎么样&#xff0c;光是安装就困难重重。 绕过限制升级了 Win11 &#xff0c;但没想到安装 W…

idea双击启动无效,idea卡顿问题

idea双击启动无效&#xff1a;大概率是关机时没有正确关闭idea&#xff0c;再次开机导致无法正常启动idea 1.通过任务管理器杀死idea进程后重启idea 2.需要修改配置 打开 &#xff08;以各自电脑实际为准&#xff09;C:\Program Files\JetBrains\IntelliJ IDEA 2020.3.1\bin&am…

LabVIEW使用图像处理检测显微图像中的白血病

LabVIEW使用图像处理检测显微图像中的白血病 人体最重要的部分是血液&#xff0c;因为它使人活着。它执行许多重要功能&#xff0c;例如转移氧气&#xff0c;二氧化碳&#xff0c;矿物质等。血液量不足会极大地影响新陈代谢&#xff0c;如果不及早治疗&#xff0c;这可能是非常…

接口自动化测试框架及接口测试自动化主要知识点

接口自动化测试框架&#xff1a; 接口测试框架&#xff1a;使用最流行的Requests进行接口测试接口请求构造&#xff1a;常见的GET/POST/PUT/HEAD等HTTP请求构造 接口测试断言&#xff1a;状态码、返回内容等断言JSON/XML请求&#xff1a;发送json\xml请求JSON/XML响应断言&…

c语言经典例题讲解(输出菱形,喝汽水问题)

目录 一、输出菱形 二、喝汽水问题 方法1&#xff1a;一步一步来 方法二&#xff1a;直接套公式 一、输出菱形 输出类似于下图的菱形&#xff1a; 通过分析&#xff1a;1、先分为上下两部分输出 2.在输出前先输出空格 3.找规律进行输出 可知&#xff0c;可令上半部分lin…

Python Opencv实践 - 图像属性相关

import numpy as np import cv2 as cv import matplotlib.pyplot as pltimg cv.imread("../SampleImages/pomeranian.png", cv.IMREAD_COLOR) plt.imshow(img[:,:,::-1])#像素操作 pixel img[320,370] print(pixel)#只获取蓝色通道的值 pixel_blue img[320,370,0]…

openwrt dns ssh相关问题

DHCP/DNS中 的技术叫dnsmasq 可配置hosts和 自定义挟持域名配置 image.png image.png 拦截优先级为挟持域名最高&#xff0c;另外需要重启服务方可生效&#xff0c;在系统&#xff0c;启动项中重启dnsmasq ssh 使用root用户SSH登录服务器出现Access Denied错误 只输入root就出现…

Python-OpenCV中的图像处理-图像金字塔

Python-OpenCV中的图像处理-图像金字塔 图像金字塔高斯金字塔拉普拉斯金字塔 金字塔图像融合 图像金字塔 同一图像的不同分辨率的子图集合&#xff0c;如果把最大的图像放在底部&#xff0c;最小的放在顶部&#xff0c;看起来像一座金字塔&#xff0c;故而得名图像金字塔。cv2…

C语言的动态分配空间C++的动态分配空间问题

动态分配空间 C&#xff1a;1、malloc 2、calloc C&#xff1a;new运算符 一 malloc malloc()&#xff1a; 这个函数用于分配一块指定大小的内存块&#xff0c;并返回一个指向该内存块的指针。语法如下&#xff1a; void* malloc(size_t size); 示例&#xff1a; int* ptr …

欧拉操作系统添加磁盘

1、查看磁盘空间 fdisk -l 2、创建新磁盘分区 fdisk /dev/vda 欢迎使用 fdisk (util-linux 2.37.2)。 更改将停留在内存中&#xff0c;直到您决定将更改写入磁盘。 使用写入命令前请三思。 This disk is currently in use - repartitioning is probably a bad idea. Its r…

(力扣)用两个栈实现队列

这里是栈的源代码&#xff1a;栈和队列的实现 当然&#xff0c;自己也可以写一个栈来用&#xff0c;对题目来说不影响&#xff0c;只要符合栈的特点就行。 题目&#xff1a; 请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作&#xff08;push、pop、pe…

c++(空间配置器)[32]

空间配置器 一级空间配置器 || 二级空间配置器 默认先走二级然后判断 二级空间配置器 一个指针指向start_free然后start_free向后移动&#xff0c;相当于哈希桶的头删和头插 8byte&#xff1a;切大补小 C的二级空间配置器按照8字节&#xff08;或者更大的倍数&#xff09;切分…

《流浪地球3》预告片流出?!网友整活竟被郭导翻牌、央视点赞!

年初《流浪地球2》掀起了一股“科幻热”&#xff0c;而这股热潮直至今日还只增不减。这不&#xff0c;一位名叫“数字生命卡兹克”的博主已经开始“整活”了&#xff01;他利用AI技术&#xff0c;自制了《流浪地球3》的预告片&#xff0c;并迅速火遍全网。 更牛的是&#xff0c…

apple pencil二代值不值得买?好用的苹果平替笔推荐

自从苹果的Pencil系列问世以来&#xff0c;在国内电容笔市场的销量大增&#xff0c;而苹果的Pencil系列&#xff0c;其的售价更是贵的让人望而却步。现在市面上有很多平替的电容笔&#xff0c;都能取代苹果的Pencil&#xff0c;用来做笔记、做批注、写写字都绰绰有余了。在这里…

【Vue+Element-plus】记录后台首页多echart图静态页面

一、页面效果 二、完整代码 Index.vue <template><div><div><DateTime /><!-- {{username}} --></div><el-row :gutter"20"><el-col :span"8"><div class"grid-content bg-purple"><P…

Python-OpenCV中的图像处理-图像轮廓

Python-OpenCV中的图像处理-图像轮廓 轮廓什么是轮廓查找轮廓绘制轮廓 轮廓特征图像的矩轮廓面积轮廓周长&#xff08;弧长&#xff09;轮廓近似凸包轮廓边界矩形 轮廓 什么是轮廓 轮廓可以简单认为成将连续的点&#xff08;连着边界&#xff09;连在一起的曲线&#xff0c;具…