YYModel使用教程

我最近在通讀 YYModel 源碼,在快速上手使用的時(shí)候,發(fā)現(xiàn)網(wǎng)上對(duì) YYModel 的使用解釋很不完善。哪怕是 YY大神自己的使用說明,我直接復(fù)制拿來用也發(fā)現(xiàn)有用不了。所以有了這篇文章!這篇文章只對(duì)我認(rèn)為需要補(bǔ)充的說明的方法進(jìn)行說明。簡(jiǎn)單用法不再贅述。(復(fù)制Json時(shí)不要把 //JSON這種復(fù)制進(jìn)去,會(huì)解析失敗的。)
先對(duì) YYModel的協(xié)議進(jìn)行說明!

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 映射到 對(duì)象的屬性。  該方法在自
+ (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。
}

使用這個(gè)方法需要在自定義類里面重寫該方法。

2.自定義容器映射

假如你的對(duì)象里面有容器(set,array,dic),你可以指定類型中的對(duì)象類型,因?yàn)閅YModel是不知道你容器中儲(chǔ)存的類型的。在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"
               }
               ]
}
\\相當(dāng)于泛型說明
+ (NSDictionary *)modelContainerPropertyGenericClass {
    return @{@"authors" : [YYAuthor class]};
}

3.根據(jù)字典返回類型

這個(gè)方法是可以根據(jù)字典里的 數(shù)據(jù) 來指定當(dāng)前對(duì)象的類型。我對(duì)這個(gè)方法的理解,假如 Person 是父類,其子類是 Man,Woman。這個(gè)時(shí)候你可以根據(jù) dic["sex"]中的 value,比如value為 NSString 的 Man,在重寫的方法里 return Man.這個(gè)時(shí)候,你當(dāng)前的字典轉(zhuǎn)模型的實(shí)例就是 Man的實(shí)例對(duì)象。(此處的 dic就是網(wǎng)絡(luò)獲取的 Json轉(zhuǎn)成的 Dict。
注:這就是多態(tài)。
+ (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];

這個(gè)時(shí)候你會(huì)發(fā)現(xiàn),當(dāng)前person的類實(shí)際上是 Man,而不是 Person。

4.白名單,黑名單

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

這兩個(gè)比較簡(jiǎn)單。
黑名單,故名思議,黑名單中的屬性不會(huì)參與字典轉(zhuǎn)模型。
白名單使用比較極端,你用了之后,只有白名單中的屬性會(huì)參與字典轉(zhuǎn)模型,其他屬性都不參與。不推薦使用。

//使用了黑名單,將來會(huì)剔除黑名單中的屬性
+ (NSArray *)modelPropertyBlacklist {
    return @[@"blackListTest"];
}

//白名單使用比較極端,只有白名單中的可以通過。    正常情況使用黑名單即可。
+ (NSArray *)modelPropertyWhitelist {
    return @[@"name"];
}

5.更改字典信息

該方法發(fā)生在字典轉(zhuǎn)模型之前。 最后對(duì)網(wǎng)絡(luò)字典做一次處理。
- (NSDictionary *)modelCustomWillTransformFromDictionary:(NSDictionary *)dic;

\\原來json
{
    "name":"Jeff",
    "age":"26",
    "sex":"Man",
    "wifeName":"ZQY"
}
\\更改后
{
}
- (NSDictionary *)modelCustomWillTransformFromDictionary:(NSDictionary *)dic{
    if ([dic[@"sex"] isEqualToString:@"Man"]) {
        return nil;//這里簡(jiǎn)單演示下,直接返回 nil。相當(dāng)于不接受男性信息。
    }
    return dic;//女性則不影響字典轉(zhuǎn)模型。
}

6.字典轉(zhuǎn)模型補(bǔ)充

- (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
}

字典轉(zhuǎn)模型結(jié)束后createdAt屬性應(yīng)該是空的,因?yàn)?code>timestamp 和 createdAt 不一樣。但你在這里賦值,手動(dòng)把timestamp的屬性賦值給_createdAt.這個(gè)有點(diǎn)類似第一點(diǎn)的 自定義屬性映射(本篇文章第一條)。
注:此處如果 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.模型轉(zhuǎn)字典補(bǔ)充

- (BOOL)modelCustomTransformToDictionary:(NSMutableDictionary *)dic;
這個(gè)方法和第6條是相對(duì)應(yīng)的關(guān)系。這里是model->json 的補(bǔ)充。
假如自己model 中有_createdAt,那 model 轉(zhuǎn)到 json 中的timestamp會(huì)被賦值。

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

注:此處如果 return NO,model->dict將失敗。

8.字典用法和數(shù)組的用法

+ (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;
這個(gè)方法的意思是只會(huì)在對(duì)字典的 value 用cls去解析。無法解析key:{key:value(cls)},這種嵌套的解析無法進(jìn)行。只會(huì)解析第一層的。

{"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);

如果對(duì)使用方法還略有不懂,可以下載我的 github 上的工程。里面都是經(jīng)過測(cè)試的。

下面的源碼是我在讀 YYModel 時(shí)添加的大量備注,和 YYModel 的簡(jiǎn)單使用介紹。
源碼地址 :
https://github.com/PomTTcat/YYModelGuideRead_JEFF

這篇文章沒講 model->json,因?yàn)槟莻€(gè)太簡(jiǎn)單了。平時(shí)使用重點(diǎn)是json->model。
最后的最后,哪里不明白可以一起交流技術(shù)!??

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容