当前位置: 首页 > news >正文

【iOS】YYModel

【iOS】YYModel

  • 前言
  • JSONModel和YYModel
  • YYModel
    • 优点
    • 使用方法
      • Model与JSON互转
      • 容器类属性
      • Model的嵌套
      • 黑名单与白名单
  • 总结

前言

YYModel是YYKit的高效组件之一,在项目中使用MVC架构时,可以简化数据处理。这里学习后可以对天气预报的仿写进行一个优化。

JSONModel和YYModel

  • JSONModel:一个用来把JSON数据和OC模型类自动映射的开源框架。JSONModel将json数据直接映射到对象中,用于简化JSON数据与数据模型之间的转换,对于获取模型嵌套数据更加方便
  • YYModel:一个高性能、轻量级的JSON模型框架。YYModel将JSON与OC对象高效地相互转换,支持复杂模型、容器类、属性映射等,适用于对性能要求高的移动应用。

总的来说,二者作用类似,但YYModel性能上相比JSONModel更加高效

YYModel

优点

  • 高性能:转换效率接近手写代码。
  • 自动类型转换:对象类型能自动转换。
  • 类型安全:在转换过程中所有的类型都会被验证,以确保类型安全。
  • 非侵入性:不需要让模型类继承自基类。
  • 轻量级:整个库只包含5个文件。
  • 文档和测试覆盖:100%文档覆盖,99.6代码覆盖。

使用方法

Model与JSON互转

JSON一般是服务器返回的数据,格式是键值对({ "name":"Tom", "age":18 }),我们在iOS开发中,需要将其转换为我们自己在OC里定义的类来承载这些数据。

这里需要注意的是:当JSON中的对象类型与Model属性不一致时,YYModel将会进行自动转换。其中自动转换不支持的值将会被忽略,以避免各种潜在的崩溃问题

使用一个简单demo实现一下:

首先别忘了保证工程里有YYModel库,最简单的方法是用CocoaPods导入第三方库:

在这里插入图片描述

如果导入运行时遇到这样的报错:

在这里插入图片描述

可能原因是旧版本的 Xcode 在编译 ARC 时依赖一个 libarclite_*.a 辅助库。而新版本的 SDK(iOS 17、18 之后)已经不再自带这些文件,但编译工具链里有些配置/脚本还在找这个库,就导致出现报错。

这里只做一个了解:

libarclite:Apple早期编译ARC代码时的一个运行时支持库,用来

  • 给ARC提供一些 runtime 辅助函数
  • 解决一些弱引用场景下的底层问题
  • 早期(iOS 5 ~ iOS 11)必须依赖它完成ARC的编译和运行

这里我们只需要把我们的 Podfile 文件修改为为 iOS 12.0 起即可:

在这里插入图片描述

我们通过调用yy_modelWithJSONyy_modelToJSONObject两个方法就可以实现JSON数据转化为model数据、model数据转化为NSObject类

#import <Foundation/Foundation.h>@interface User : NSObject@property(nonatomic, assign) UInt64 uidNum;//C语言基本整数类型,无符号的64位整数
@property(nonatomic, copy) NSString *name;
@property(nonatomic, strong) NSDate *createdTime;@end#import "ViewController.h"
#import "User.h"
#import "YYModel.h"@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad {[super viewDidLoad];NSDictionary *json = @{@"uidNum":@123, @"name":@"Cherry", @"createdTime":@"2025-09-17T15:44:00+0000"};User *user = [User yy_modelWithJSON:json];NSLog(@"name:%@, uidNum:%llu, createdTime:%@", user.name, user.uidNum, user.createdTime);NSDictionary *jsonBack = [user yy_modelToJSONObject];NSLog(@"json:%@", jsonBack);
}@end

编译结果:
在这里插入图片描述

容器类属性

在JSON里经常会出现数组或集合,例如我们天气预报中网络请求得到的数据:

{code = 200;location =     ({adm1 = "\U9655\U897f\U7701";adm2 = "\U897f\U5b89";country = "\U4e2d\U56fd";fxLink = "https://www.qweather.com/weather/xi'an-101110101.html";id = 101110101;isDst = 0;lat = "34.34321";lon = "108.93965";name = "\U897f\U5b89";rank = 11;type = city;tz = "Asia/Shanghai";utcOffset = "+08:00";});refer =     {license =         ("QWeather Developers License");sources =         (QWeather);};
}

我们这里的location就是一个数组,而这个数组里包含了Model。遇到这种JSON里出现容器类属性的情况,我们需要调用+(NSDictionary<NSString *,**id**> *)modelContainerPropertyGenericClass方法。

#import <Foundation/Foundation.h>
#import "LocationModel.h"
#import "YYModel.h"
#import "AFNetworking.h"@interface Model : NSObject<YYModel>@property(nonatomic, strong) NSString *code;
@property(nonatomic, copy) NSArray *location;@end#import <Foundation/Foundation.h>
#import "AFNetworking.h"
#import "Model.h"@interface LocationModel : NSObject@property(nonatomic, strong) NSString *adm1;
@property(nonatomic, strong) NSString *adm2;
@property(nonatomic, strong) NSString *country;
@property(nonatomic, strong) NSString *fxLink;
@property(nonatomic, strong) NSString *id;
@property(nonatomic, strong) NSString *isDst;
@property(nonatomic, strong) NSString *lat;
@property(nonatomic, strong) NSString *lon;
@property(nonatomic, strong) NSString *name;
@property(nonatomic, strong) NSString *rank;
@property(nonatomic, strong) NSString *type;
@property(nonatomic, strong) NSString *tz;
@property(nonatomic, strong) NSString *utcOffset;-(void)dataLoad;@end
#import "LocationModel.h"@implementation LocationModel-(void)dataLoad {NSString *cityName = @"西安";NSString *city = [cityName stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];NSString *urlString = [NSString stringWithFormat:@"https://geoapi.qweather.com/v2/city/lookup?location=%@&key=3344bfece6c74eaa911a5f857c30df82", city];[[AFHTTPSessionManager manager] GET:urlString parameters:nil headers:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {//NSLog(@"%@", responseObject);Model *model = [Model yy_modelWithJSON:responseObject];NSDictionary *json = [model yy_modelToJSONObject];NSLog(@"%@", json);} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {NSLog(@"error");}];
}@end#import "Model.h"@implementation Model+(NSDictionary<NSString *,id> *)modelContainerPropertyGenericClass {return @{@"location":[LocationModel class]};
}@end

整个过程的逻辑是,网络请求后,先读取第一层属性(code,location等),当读取到类似于location容器类属性时,再调用+(NSDictionary<NSString *,id> *)modelContainerPropertyGenericClass方法告诉返回Location这个类对象,也就是我们在这个类中写的NSString类型属性,这样我们就会得到输出:

在这里插入图片描述

Model的嵌套

让一个Model的一个属性是另一个Model类的对象即可。

#import <Foundation/Foundation.h>@interface Author : NSObject@property(nonatomic, strong) NSString *name;
@property(nonatomic, strong) NSString *birthday;@end#import <Foundation/Foundation.h>
#import "Author.h"@interface Book : NSObject@property(nonatomic, strong) NSString *book;
@property(nonatomic, assign) NSUInteger page;
@property(nonatomic, strong) Author *author;@end
{"author":{"name":"J.K.Rowling","birthday":"1965-07-31T00:00:00+0000"},"book":"Harry Potter","page":256
}

黑名单与白名单

  • 黑名单:指定哪些属性不参与JSON转换。
+(NSArray<NSString *> *)modelPropertyBlacklist {return @[@"location"];
}

这部分代码加在我们上面的demo中,location将不参与JSON转换,编译结果就会改变:在这里插入图片描述

  • 白名单:指定只有哪些属性参与JSON转换,其余的都会被忽略。
+(NSArray<NSString *> *)modelPropertyWhitelist {return @[@"code"];
}

白名单使得只有code能参与JSON转换,编译结果能实现同样的效果:

在这里插入图片描述

总结

这样,我们就可以更方便地将网络请求中得到的数据转化成我们的OC对象,方便对数据操作处理。

http://www.dtcms.com/a/395307.html

相关文章:

  • 修改docker配置使其支持本机tcp连接
  • ReportFragment:Android 生命周期的桥梁与兼容性解决方案
  • 力扣Hot100--234.回文链表
  • 视觉语言大模型(VLM)的产业落地:从Qwen-VL技术解析到医疗、车险行业革新
  • 零基础新手小白快速了解掌握服务集群与自动化运维(七)Nginx模块--Nginx Web服务
  • 一个硬盘选MBR 还是GPT
  • 【含文档+PPT+源码】基于GPT+SpringBoot的个人健康管理与咨询系统设计与实现
  • 【项目实战 Day5】springboot + vue 苍穹外卖系统(Redis + 店铺经营状态模块 完结)
  • 旧衣回收小程序:非技术视角下的价值重构与发展前景
  • 使用vue-i18n实现语言切换
  • 做小程序找哪家公司,解析小程序开发定制公司哪家适合你
  • 【python】python进阶——math模块
  • NHD-6108 全自动远、近光检测仪:智能高效的汽车灯光检测方案
  • 《 Linux 点滴漫谈: 一 》开源之路:Linux 的历史、演进与未来趋势
  • C#和微软System.Speech.Synthesis库实现语音合成
  • C++概述 (一)
  • 【开题答辩全过程】以 基于springboot的高校仪器共享管理系统设计和实现为例,包含答辩的问题和答案
  • 【python】FastAPI简介
  • IDEA lombok注解无效的问题,运行时提示java: 找不到符号或者方法
  • Windows 系统部署 Kronos 金融 K 线基础模型——基于 EPGF 架构
  • 010 Rust流程控制
  • MyBatisPlus快速入门:简化CRUD操作
  • 网络编程套接字(三)---简单的TCP网络程序
  • 背景建模(基于视频,超炫)项目实战!
  • ios26版本回退到ios18
  • OpenCV直方图比较:原理与四种方法详解
  • OpenCV - 图像金字塔
  • 寄存柜频繁维护还卡顿?杰和IB2-281主板:智能化升级高效省心
  • 海外短剧系统开发:多语言适配与跨地区部署的架构实践
  • JVM内存模型详解:看内存公寓如何分配“房间“