目录
[什么是YYModel ?](#什么是YYModel ?)
[如何使用YYModel ?](#如何使用YYModel ?)
什么是YYModel ?
YYModel
是一个用于 iOS 和 macOS 开发的高性能的模型框架,主要用于对象和 JSON(JavaScript Object Notation)数据之间的转换。
主要特点和功能包括:
- 高性能转换:在对象和 JSON 之间进行转换时速度非常快,能高效地处理大量数据。
- 自动映射 :可以自动将 JSON 数据中的键值对映射到模型对象的属性上,无需手动编写大量的映射代码。例如,当 JSON 中的一个键与模型对象的属性名相同时,
YYModel
可以自动将该键对应的值赋值给这个属性。 - 支持复杂数据结构:能够处理包含嵌套对象、数组等复杂数据结构的 JSON 数据,并且可以将这些复杂结构映射到相应的模型对象结构中。
- 类型安全:确保在转换过程中数据类型的正确性,减少因类型不匹配而导致的错误。
- 可扩展性:可以方便地进行扩展和定制,以满足特定的业务需求。
使用YYModel
可以极大地简化 iOS 和 macOS 应用程序中数据模型的处理,提高开发效率和代码的可维护性。
如何使用YYModel ?
YYModel的主体工作就是JSON转模型。
最简单的Model
定义一个模型类,该类的属性要与 JSON 数据中的键相对应。
例如这段YYModel原作者github使用文档里的示例:
objectivec
// 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
// 将 JSON (NSData,NSString,NSDictionary) 转换为 Model:
User *user = [User yy_modelWithJSON:json];
// 将 Model 转换为 JSON 对象:
NSDictionary *json = [user yy_modelToJSONObject];
这段代码中JSON数据的字典键与Model中属性名一一对应,最下面几行代码则是调用方法实现Json数据到Model的转换和Model到JSON的转换
与网络请求结合
objectivec
void dataload {
NSString* urlString = @"https://devapi.qweather.com/v7/weather/3d?location=101010100&key=34e1f7a3ef5544d393fcafaea08f0f1b";
NSURL* url = [NSURL URLWithString:urlString];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if (!error && data) {
NSError *jsonError;
NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:data options:0 error:&jsonError];
if (!jsonError && [jsonDict isKindOfClass:[NSDictionary class]]) {
AModel *model = [AModel yy_modelWithDictionary:jsonDict];
NSLog(@"%@",model);
}
} else {
NSLog(@"Error: %@", error);
}
}];
[task resume];
}
属性为容器类的Model
有时JSON数据中的键对应的是一个容器类,这时我们就需要调用YYModel协议中的方法来告诉这个类它里面放的元素应该是什么类型的
这个方法就是**+ (NSDictionary *)modelContainerPropertyGenericClass**
在方法中,我们直接返回元素的类型。
objectivec
{
"code": "200",
"updateTime": "2024-10-20T16:18+08:00",
"fxLink": "https://www.qweather.com/weather/beijing-101010100.html",
"daily": [
{
"fxDate": "2024-10-20",
"sunrise": "06:31",
"sunset": "17:29",
"moonrise": "19:01",
"moonset": "09:48",
"moonPhase": "亏凸月",
"moonPhaseIcon": "805",
"tempMax": "12",
"tempMin": "1",
"iconDay": "305",
"textDay": "小雨",
"iconNight": "151",
"textNight": "多云",
"wind360Day": "180",
"windDirDay": "南风",
"windScaleDay": "1-3",
"windSpeedDay": "3",
"wind360Night": "180",
"windDirNight": "南风",
"windScaleNight": "1-3",
"windSpeedNight": "3",
"humidity": "58",
"precip": "1.0",
"pressure": "1016",
"vis": "25",
"cloud": "55",
"uvIndex": "2"
},
{
"fxDate": "2024-10-21",
"sunrise": "06:32",
"sunset": "17:28",
"moonrise": "19:51",
"moonset": "11:02",
"moonPhase": "亏凸月",
"moonPhaseIcon": "805",
"tempMax": "14",
"tempMin": "6",
"iconDay": "101",
"textDay": "多云",
"iconNight": "305",
"textNight": "小雨",
"wind360Day": "225",
"windDirDay": "西南风",
"windScaleDay": "1-3",
"windSpeedDay": "3",
"wind360Night": "0",
"windDirNight": "北风",
"windScaleNight": "1-3",
"windSpeedNight": "16",
"humidity": "48",
"precip": "0.0",
"pressure": "1017",
"vis": "25",
"cloud": "25",
"uvIndex": "4"
},
{
"fxDate": "2024-10-22",
"sunrise": "06:33",
"sunset": "17:26",
"moonrise": "20:49",
"moonset": "12:07",
"moonPhase": "亏凸月",
"moonPhaseIcon": "805",
"tempMax": "16",
"tempMin": "4",
"iconDay": "101",
"textDay": "多云",
"iconNight": "150",
"textNight": "晴",
"wind360Day": "0",
"windDirDay": "北风",
"windScaleDay": "1-3",
"windSpeedDay": "16",
"wind360Night": "270",
"windDirNight": "西风",
"windScaleNight": "1-3",
"windSpeedNight": "3",
"humidity": "44",
"precip": "0.0",
"pressure": "1014",
"vis": "24",
"cloud": "25",
"uvIndex": "2"
}
],
"refer": {
"sources": [
"QWeather"
],
"license": [
"CC BY-SA 4.0"
]
}
}
比如这段JSON数据,daily对应的属性是一个数组,而这个数组中包含三个字典,这三个字典其实可以转化成同一种model,因此我们就需要调用方法来告诉model,daily数组中所存放的元素是一个model。
注意,在声明 + (NSDictionary *)modelContainerPropertyGenericClass这个方法时,要让该类遵守YYModel协议。
然后我们在方法中返回元素的类型
objectivec
+ (NSDictionary *)modelContainerPropertyGenericClass {
return @{@"daily":[dailyModel class]};
}
在model中 实现这个方法,我们使用一个字典,将daily对应的键值设置为我们要设置的dailyModel属性,这里的dailyModel也就是数组中所存放元素的类型。
白名单和黑名单
关于黑名单和白名单,其实就是通过两个方法来屏蔽和选中一些属性,让model不要处理或者只处理某些属性。
- 白名单是一个指定的属性列表,只有在这个列表中的属性会被
YYModel
在映射过程中处理。这意味着当从 JSON 数据转换为模型对象或者从模型对象转换为 JSON 数据时,只有白名单中的属性会被考虑。 - 黑名单与白名单相反,是一个指定的属性列表,这些属性在映射过程中会被
YYModel
忽略。
objectivec
+ (NSArray<NSString *> *)modelPropertyWhitelist {
return @[@"name", @"age"];
}
+ (NSArray<NSString *> *)modelPropertyBlacklist {
return @[@"secretInfo"];
}
Model的嵌套
关于model的嵌套,其实就是将model的属性设为另一个model,model其实是NSObject的子类,所以不需要多加处理,直接设为属性即可
结语
关于YYModel,其实还有一些Model和字典之间的转换,以及匹配不到字典对应键时的处理,这些东西之后会再完善。