【iOS】YYModel的初步学习
YYModel的初步学习
文章目录
- YYModel的初步学习
- 前言
- 与JSONModel对比
- YYModel的优势
- 如何使用YYModel
- 最简单的Model形式
- 容器类属性
- 白名单和黑名单
- Model的嵌套
- 小结
前言
随着时代的发展,iOS解析JSON数据的第三方库越来越多,原先的JSONModel的性能上的问题逐渐显现,现在我们可以采用更加高效的第三方库YYModel。
与JSONModel对比
时间消耗(在 iPhone 6 上处理 GithubUser 10000 次):

这里我们可以看出YYModel的性能其实超过了JSONModel,笔者在下文中仅仅介绍对于YYModel的使用,至于他与JSONModel的源码笔者会之后再进行学习。
YYModel的优势
- 高性能:转换性能接近手写代码。
- 自动类型转换:对象类型可以自动转换。
- 类型安全:将验证所有数据类型以确保在转换过程中类型安全。
- 非侵入式:无需使模型类继承其他基类。
- 轻量化:此库仅包含 5 个文件。
- 文档和单元测试:100% 的文档覆盖率,99.6% 的代码覆盖率。
如何使用YYModel
最简单的Model形式
// JSON:
{"uid":123456,"name":"Harry","created":"1965-07-31T00:00:00+0000"
}// Model:
@interface User : NSObject
@property UInt64 uid;
@property NSString *name;
@property NSDate *created;
@end
@implementation User
@end// Convert json to model:
User *user = [User yy_modelWithJSON:json];// Convert model to json:
NSDictionary *json = [user yy_modelToJSONObject];
我们使用YYModel的时候,只需要按照JSON数据中的名字,然后创建一个对象中设置属性名字和JSON数据中相同,然后我们需要在网络请求中调用yy_modelWithJSON和yy_modelToJSONObject这两个方法。一个是将JSON转化成model数据,另一个则是将model数据转化成NSObject这两个类。
这里我们简单将这段代码放在网络请求中:
-(void)dataLoad {NSString* urlString = @"https://devapi.qweather.com/v7/weather/3d?location=101010100&key=2211750bdc834763ba3c5f57ce98c307";//NSURL* url = [NSURL URLWithString:urlString];[[AFHTTPSessionManager manager] GET:urlString parameters:nil headers:nil progress:^(NSProgress * _Nonnull downloadProgress) {} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {tryModel* model = [tryModel yy_modelWithJSON:responseObject];NSDictionary* dirty = [model yy_modelToJSONObject];NSLog(@"%@", dirty);} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {NSLog(@"error");}];
}
我们只需要简单结合网络请求和YYModel便可以实现对于JSON数据的一个解析,这里笔者采用了之前用过的和风天气的api
容器类属性
这里先给出我们这里的JSON数据:
{"code": "200","updateTime": "2024-10-08T20:18+08:00","fxLink": "https://www.qweather.com/weather/beijing-101010100.html","daily": [{"fxDate": "2024-10-08","sunrise": "06:18","sunset": "17:47","moonrise": "11:40","moonset": "20:33","moonPhase": "蛾眉月","moonPhaseIcon": "801","tempMax": "23","tempMin": "10","iconDay": "100","textDay": "晴","iconNight": "151","textNight": "多云","wind360Day": "180","windDirDay": "南风","windScaleDay": "1-3","windSpeedDay": "3","wind360Night": "180","windDirNight": "南风","windScaleNight": "1-3","windSpeedNight": "3","humidity": "64","precip": "0.0","pressure": "1010","vis": "25","cloud": "25","uvIndex": "4"},{"fxDate": "2024-10-09","sunrise": "06:19","sunset": "17:46","moonrise": "12:41","moonset": "21:28","moonPhase": "蛾眉月","moonPhaseIcon": "801","tempMax": "20","tempMin": "11","iconDay": "305","textDay": "小雨","iconNight": "151","textNight": "多云","wind360Day": "90","windDirDay": "东风","windScaleDay": "1-3","windSpeedDay": "3","wind360Night": "0","windDirNight": "北风","windScaleNight": "1-3","windSpeedNight": "16","humidity": "24","precip": "1.0","pressure": "1012","vis": "24","cloud": "55","uvIndex": "3"},{"fxDate": "2024-10-10","sunrise": "06:20","sunset": "17:44","moonrise": "13:36","moonset": "22:32","moonPhase": "上弦月","moonPhaseIcon": "802","tempMax": "21","tempMin": "7","iconDay": "100","textDay": "晴","iconNight": "150","textNight": "晴","wind360Day": "0","windDirDay": "北风","windScaleDay": "1-3","windSpeedDay": "3","wind360Night": "225","windDirNight": "西南风","windScaleNight": "1-3","windSpeedNight": "3","humidity": "42","precip": "0.0","pressure": "1010","vis": "25","cloud": "25","uvIndex": "4"}],"refer": {"sources": ["QWeather"],"license": ["CC BY-SA 4.0"]}
}
这里我们可以看到这里的daily里面包含了一个数组,而那个数组里面有包含了另一个Model。所以说这里的JSON数据包含了一个容器类的属性,这里我们需要调用一下+ (NSDictionary *)modelContainerPropertyGenericClass这个方法,这个方法是让我们的NSArray或者NSSet这些容器知道里面的存储的元素是什么对象:
- 这里注意下让这个类继承YYModel这个协议,否则会找不到这个方法
@interface Model : NSObject
@property (nonatomic, strong) NSString* fxDate;
@property (nonatomic, strong) NSString* sunrise;
@property (nonatomic, strong) NSString* sunset;
@property (nonatomic, strong) NSString* moonrise;
@property (nonatomic, strong) NSString* moonset;@property (nonatomic, strong) NSString* moonPhase;
//@property (nonatomic, strong) NSString* moonPhaseIcon;
@property (nonatomic, strong) NSString* tempMax;
@property (nonatomic, strong) NSString* tempMin;
@property (nonatomic, strong) NSString* iconDay;
@property (nonatomic, strong) NSString* textDay;
@property (nonatomic, strong) NSString* iconNight;
@property (nonatomic, strong) NSString* textNight;
@property (nonatomic, strong) NSString* wind360Day;
@property (nonatomic, strong) NSString* windDirDay;
@property (nonatomic, strong) NSString* windScaleDay;
@property (nonatomic, strong) NSString* windSpeedDay;
@property (nonatomic, strong) NSString* wind360Night;
@property (nonatomic, strong) NSString* windDirNight;
@property (nonatomic, strong) NSString* windScaleNight;
@property (nonatomic, strong) NSString* windSpeedNight;
@property (nonatomic, strong) NSString* humidity;
@property (nonatomic, strong) NSString* precip;
@property (nonatomic, strong) NSString* pressure;
@property (nonatomic, strong) NSString* vis;
@property (nonatomic, strong) NSString* cloud;
@property (nonatomic, strong) NSString* uvIndex;
@end
@interface tryModel : NSObject<YYModel>
@property (nonatomic, strong) NSString* code;
@property (nonatomic, copy) NSArray* daily;
@end
+ (NSDictionary *)modelContainerPropertyGenericClass {return @{@"daily":[Model class]};
}
这里我们可以看到这里的数组里面存储的也是一个Model,所以我们在这个方法里面给他一个字典让这个属性对应Model的这个class,所以我们就可以让他进行一个Model的解析了。下面给出网络请求和YYModel数据结合
@implementation Model
-(void)dataLoad {NSString* urlString = @"https://devapi.qweather.com/v7/weather/3d?location=101010100&key=2211750bdc834763ba3c5f57ce98c307";//NSURL* url = [NSURL URLWithString:urlString];[[AFHTTPSessionManager manager] GET:urlString parameters:nil headers:nil progress:^(NSProgress * _Nonnull downloadProgress) {} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {tryModel* model = [tryModel yy_modelWithJSON:responseObject];NSDictionary* dirty = [model yy_modelToJSONObject];NSLog(@"%@", dirty);} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {NSLog(@"error");}];
}
@end
@implementation tryModel+ (NSDictionary *)modelContainerPropertyGenericClass {return @{@"daily":[Model class]};
}
@end
打印结果:
code = 200;daily = ({cloud = 55;fxDate = "2024-10-09";humidity = 26;iconDay = 305;iconNight = 151;moonPhase = "\U86fe\U7709\U6708";moonrise = "12:41";moonset = "21:28";precip = "1.0";pressure = 1013;sunrise = "06:19";sunset = "17:46";tempMax = 21;tempMin = 11;textDay = "\U5c0f\U96e8";textNight = "\U591a\U4e91";uvIndex = 3;vis = 24;wind360Day = 270;wind360Night = 0;windDirDay = "\U897f\U98ce";windDirNight = "\U5317\U98ce";windScaleDay = "1-3";windScaleNight = "1-3";windSpeedDay = 3;windSpeedNight = 16;},{cloud = 25;fxDate = "2024-10-10";humidity = 40;iconDay = 100;iconNight = 150;moonPhase = "\U4e0a\U5f26\U6708";moonrise = "13:36";moonset = "22:32";precip = "0.0";pressure = 1011;sunrise = "06:20";sunset = "17:44";tempMax = 21;tempMin = 8;textDay = "\U6674";textNight = "\U6674";uvIndex = 4;vis = 25;wind360Day = 0;wind360Night = 225;windDirDay = "\U5317\U98ce";windDirNight = "\U897f\U5357\U98ce";windScaleDay = "1-3";windScaleNight = "1-3";windSpeedDay = 3;windSpeedNight = 3;},{cloud = 25;fxDate = "2024-10-11";humidity = 47;iconDay = 100;iconNight = 150;moonPhase = "\U76c8\U51f8\U6708";moonrise = "14:22";moonset = "23:44";precip = "0.0";pressure = 1015;sunrise = "06:21";sunset = "17:42";tempMax = 23;tempMin = 11;textDay = "\U6674";textNight = "\U6674";uvIndex = 4;vis = 25;wind360Day = 180;wind360Night = 45;windDirDay = "\U5357\U98ce";windDirNight = "\U4e1c\U5317\U98ce";windScaleDay = "1-3";windScaleNight = "1-3";windSpeedDay = 3;windSpeedNight = 3;});
}
Type: Notice | Timestamp: 2024-10-09 10:38:01.586475+08:00 | Process: YYModel | Library: YYModel | TID: 0x12795b1
这里就可以打印出JSON数据
白名单和黑名单
+ (NSArray<NSString *> *)modelPropertyBlacklist {return @[@"updateTime"];
}//这个方法不会处理JSON数据中的这个数据
+ (NSArray<NSString *> *)modelPropertyWhitelist {return @[@"daily"];
}//这个方法会让提仅仅处理JSON中的这个数据
如果实现这两个方法可以让我们获得我们所需要的数据
Model的嵌套
什么也不用做,我们只需要让一个Model的一个属性设置成另一个Model就可以了
例如:
// JSON
{"author":{"name":"J.K.Rowling","birthday":"1965-07-31T00:00:00+0000"},"name":"Harry Potter","pages":256
}// Model: 什么都不用做,转换会自动完成
@interface Author : NSObject
@property NSString *name;
@property NSDate *birthday;
@end
@implementation Author
@end@interface Book : NSObject
@property NSString *name;
@property NSUInteger pages;
@property Author *author; //Book 包含 Author 属性
@end
@implementation Book
@end
小结
本篇文章简单介绍了如何将网络请求中得到的数据转化成我们OC中的对象,方便我们对于数据进行操作处理。
