YYModel使用教程

我最近在通读 YYModel 源码,在快速上手使用的时候,发现网上对 YYModel 的使用解释很不完善。哪怕是 YY大神自己的使用说明,我直接复制拿来用也发现有用不了。所以有了这篇文章!这篇文章只对我认为需要补充的说明的方法进行说明。简单用法不再赘述。(复制Json时不要把 //JSON这种复制进去,会解析失败的。)
先对 YYModel的协议进行说明!

1.自定义属性映射

+ (nullable NSDictionary<NSString *, id> *)modelCustomPropertyMapper;

//自定义类的属性
@property NSString      *name;
@property NSInteger     page;
@property NSString      *desc;
@property NSString      *bookID;
//JSON
{
    "n":"Harry Pottery",
    "p": 256,
    "ext" : {
        "desc" : "A book written by J.K.Rowing."
    },
    "id" : 100010
}
//custom属性,让 json key 映射到 对象的属性。  该方法在自
+ (NSDictionary *)modelCustomPropertyMapper {
    return @{@"name" : @"n",
             @"page" : @"p",
             @"desc" : @"ext.desc",                 //key.path
             @"bookID" : @[@"ID",@"id",@"book_id"]};
    //从 json 过来的key 可以是id,ID,book_id。例子中 key 为 id。
}

使用这个方法需要在自定义类里面重写该方法。

2.自定义容器映射

假如你的对象里面有容器(set,array,dic),你可以指定类型中的对象类型,因为YYModel是不知道你容器中储存的类型的。在dic中,你指定的是它 value 的类型。
+ ( NSDictionary<NSString *, id> *)modelContainerPropertyGenericClass;

@interface YYAuthor : NSObject
@property (nonatomic, strong) NSString *name;
@property (nonatomic, assign) NSDate *birthday;
@end
@interface User : NSObject
@property UInt64        uid;
@property NSString      *bookname;
@property (nonatomic, strong)   NSMutableArray<YYAuthor *>    *authors;
@end
{
    "uid":123456,
    "bookname":"Harry",
    "authors":[
               {
               "birthday":"1991-07-31T08:00:00+0800",
               "name":"G.Y.J.jeff"
               },
               {
               "birthday":"1990-07-31T08:00:00+0800",
               "name":"Z.Q.Y,jhon"
               }
               ]
}
\\相当于泛型说明
+ (NSDictionary *)modelContainerPropertyGenericClass {
    return @{@"authors" : [YYAuthor class]};
}

3.根据字典返回类型

这个方法是可以根据字典里的 数据 来指定当前对象的类型。我对这个方法的理解,假如 Person 是父类,其子类是 Man,Woman。这个时候你可以根据 dic["sex"]中的 value,比如value为 NSString 的 Man,在重写的方法里 return Man.这个时候,你当前的字典转模型的实例就是 Man的实例对象。(此处的 dic就是网络获取的 Json转成的 Dict。
注:这就是多态。
+ (nullable Class)modelCustomClassForDictionary:(NSDictionary*)dictionary;

{
    "name":"Jeff",
    "age":"26",
    "sex":"Man",
    "wifeName":"ZQY"
}
//.h
@interface Person : NSObject
@property (nonatomic, copy)     NSString        *name;
@property (nonatomic, assign)   NSUInteger      age;
@end

@interface Man : Person
@property (nonatomic, copy)     NSString        *wifeName;
@end

@interface Woman : Person
@property (nonatomic, copy)     NSString        *husbandName;
@end

//.m
+ (Class)modelCustomClassForDictionary:(NSDictionary*)dictionary {
    if (dictionary[@"sex"] != nil) {
        NSString *runClass = dictionary[@"sex"];
        return NSClassFromString(runClass);
    } else {
        return [self class];
    }
}

    NSData *dataPerson = [self dataWithPath:@"person"];
    Person *person = [Person modelWithJSON:dataPerson];
    [person modelDescription];

这个时候你会发现,当前person的类实际上是 Man,而不是 Person。

4.白名单,黑名单

+ (nullable NSArray<NSString *> *)modelPropertyBlacklist;                           黑名单
+ (nullable NSArray<NSString *> *)modelPropertyWhitelist;                           白名单

这两个比较简单。
黑名单,故名思议,黑名单中的属性不会参与字典转模型。
白名单使用比较极端,你用了之后,只有白名单中的属性会参与字典转模型,其他属性都不参与。不推荐使用。

//使用了黑名单,将来会剔除黑名单中的属性
+ (NSArray *)modelPropertyBlacklist {
    return @[@"blackListTest"];
}

//白名单使用比较极端,只有白名单中的可以通过。    正常情况使用黑名单即可。
+ (NSArray *)modelPropertyWhitelist {
    return @[@"name"];
}

5.更改字典信息

该方法发生在字典转模型之前。 最后对网络字典做一次处理。
- (NSDictionary *)modelCustomWillTransformFromDictionary:(NSDictionary *)dic;

\\原来json
{
    "name":"Jeff",
    "age":"26",
    "sex":"Man",
    "wifeName":"ZQY"
}
\\更改后
{
}
- (NSDictionary *)modelCustomWillTransformFromDictionary:(NSDictionary *)dic{
    if ([dic[@"sex"] isEqualToString:@"Man"]) {
        return nil;//这里简单演示下,直接返回 nil。相当于不接受男性信息。
    }
    return dic;//女性则不影响字典转模型。
}

6.字典转模型补充

- (BOOL)modelCustomTransformFromDictionary:(NSDictionary *)dic;

@interface User : NSObject
@property UInt64        uid;
@property NSDate        *created;
@property NSDate        *createdAt;
@property NSString      *bookname;
@end
{
    "uid":123456,
    "bookname":"Harry",
    "created":"1965-07-31T00:00:00+0000",
    "timestamp" : 1445534567
}

字典转模型结束后createdAt属性应该是空的,因为timestampcreatedAt 不一样。但你在这里赋值,手动把timestamp的属性赋值给_createdAt.这个有点类似第一点的 自定义属性映射(本篇文章第一条)。
注:此处如果 return NO,dic->model将失败。

- (BOOL)modelCustomTransformFromDictionary:(NSDictionary *)dic {
    NSNumber *timestamp = dic[@"timestamp"];
    if (![timestamp isKindOfClass:[NSNumber class]]) return NO;
    _createdAt = [NSDate dateWithTimeIntervalSince1970:timestamp.floatValue];
    return YES;
}

7.模型转字典补充

- (BOOL)modelCustomTransformToDictionary:(NSMutableDictionary *)dic;
这个方法和第6条是相对应的关系。这里是model->json 的补充。
假如自己model 中有_createdAt,那 model 转到 json 中的timestamp会被赋值。

- (BOOL)modelCustomTransformToDictionary:(NSMutableDictionary *)dic {
    if (!_createdAt) return NO;
    dic[@"timestamp"] = @(_createdAt.timeIntervalSince1970);
    return YES;
}

注:此处如果 return NO,model->dict将失败。

8.字典用法和数组的用法

+ (nullable NSArray *)modelArrayWithClass:(Class)cls json:(id)json;
+ (nullable NSDictionary *)modelDictionaryWithClass:(Class)cls json:(id)json;
 [{"birthday":"1991-07-31T08:00:00+0800",
  "name":"G.Y.J.jeff"},
  {"birthday":"1990-07-31T08:00:00+0800",
  "name":"Z.Q.Y,jhon"}]
@class YYAuthor;
@interface YYAuthor : NSObject
@property (nonatomic, strong) NSString *name;
@property (nonatomic, assign) NSDate *birthday;
@end
    NSData *dataArr = [self dataWithPath:@"arrayTest"];
    NSArray *arrT = [NSArray modelArrayWithClass:[YYAuthor class] json:dataArr];
    NSLog(@"arrT = %@",arrT);

+ (NSDictionary *)modelDictionaryWithClass:(Class)cls json:(id)json;
这个方法的意思是只会在对字典的 value 用cls去解析。无法解析key:{key:value(cls)},这种嵌套的解析无法进行。只会解析第一层的。

{"user1": {
    "birthday":"1990-07-31T08:00:00+0800",
    "name":"1Z.Q.Y,jhon"
},"user2":{
    "birthday":"1990-07-31T08:00:00+0800",
    "name":"2Z.Q.Y,jhon"
},"user3":{"user4":{
    "birthday":"1990-07-31T08:00:00+0800",
    "name":"3Z.Q.Y,jhon"
}}}
    NSData *dataDict = [self dataWithPath:@"dicTest"];
    NSDictionary *dicT = [NSDictionary modelDictionaryWithClass:[YYAuthor class] json:dataDict];
    NSLog(@"dicT = %@",dicT);

如果对使用方法还略有不懂,可以下载我的 github 上的工程。里面都是经过测试的。

下面的源码是我在读 YYModel 时添加的大量备注,和 YYModel 的简单使用介绍。
源码地址 :
https://github.com/PomTTcat/YYModelGuideRead_JEFF

这篇文章没讲 model->json,因为那个太简单了。平时使用重点是json->model。
最后的最后,哪里不明白可以一起交流技术!🙂

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容