Mantle的使用
要實(shí)現(xiàn)的功能
我要舉得例子來自豆瓣電影喜颁,根據(jù)某電影ID從豆瓣上把數(shù)據(jù)抓取出來,通過Mantle格式化為我們需要的Model坎吻。
豆瓣電影獲取到后是一串JSON,類似下面:
{
"alt": "http://movie.douban.com/movie/4212172",
"alt_title": "12生肖",
"attrs": {
"cast": [
"成龍 Jackie Chan",
"權(quán)相宇 Sang-woo Kwone",
"廖凡 Fan Liao",
"姚星彤 Xingtong Yao",
"張藍(lán)心 Lanxin Zhang",
"白露娜 Laura Weissbecker",
"劉承俊 Sung-jun Yoo",
"吳彥祖 Daniel Wu",
"舒淇 Qi Shu",
"李宗盛 Jonathan Lee",
"陳柏霖 Bo-lin Chen",
"盧惠光 Ken Lo",
"淺野長(zhǎng)英",
"白冰 Bing Bai",
"林鵬 Peng Lin"
],
"country": [
"中國(guó)大陸",
"香港"
],
"director": [
"成龍 Jackie Chan"
],
"language": [
"英語",
"漢語普通話",
"粵語",
"法語",
"西班牙語"
],
"movie_duration": [
"122分鐘"
],
"movie_type": [
"喜劇",
"動(dòng)作",
"冒險(xiǎn)"
],
"pubdate": [
"2012-12-12(香港國(guó)際電影節(jié))",
"2012-12-20(中國(guó)大陸/香港)"
],
"title": [
"十二生肖"
],
"website": [
"hbpictures.ayomovie.com/12shengxiao"
],
"writer": [
"成龍 Jackie Chan",
"唐季禮 Stanley Tong",
"鄧景生 Edward Tang",
"陳勛奇 Frankie Chan"
],
"year": [
"2012"
]
},
"author": [
{
"name": "成龍 Jackie Chan"
}
],
"id": "http://api.douban.com/movie/4212172",
"image": "http://img3.douban.com/view/movie_poster_cover/ipst/public/p1826580562.jpg",
"mobile_link": "http://m.douban.com/movie/subject/4212172/",
"rating": {
"average": "6.7",
"max": 10,
"min": 0,
"numRaters": 159114
},
"summary": "當(dāng)年英法聯(lián)軍火燒圓明園,致使大批珍貴文物流落海外帜慢,其中四尊十二生肖獸首最引人關(guān)注,不僅惹出國(guó)內(nèi)外的廣泛爭(zhēng)論唯卖,更有收藏家開出天價(jià)競(jìng)拍這幾尊珍品粱玲。當(dāng)然,其間不乏奸邪的文物販子拜轨,試圖通過偷盜的手段獲取寶貝抽减。以此為契機(jī),正在度假的國(guó)際大盜JC(成龍 飾)隆重登場(chǎng)撩轰。JC背后有一支 Simon(權(quán)相宇 飾)胯甩、David(廖凡 飾)、Bonnie(張藍(lán)心 飾)等人共同組成的超專業(yè)團(tuán)隊(duì)堪嫂,他們一同遠(yuǎn)赴巴黎偎箫,尋求國(guó)寶鑒定專家Coco(姚星彤 飾)的幫助。經(jīng)過周密細(xì)致的準(zhǔn)備皆串,JC等人一步步逼近重兵把守的獸首淹办,而圍繞珍寶不可避免爆發(fā)連番驚險(xiǎn)火爆的打斗與追逐。
在這一過程中恶复,JC似曾被利益和金錢泯滅的愛國(guó)之心漸漸蘇醒……",
"tags": [
{
"count": 34460,
"name": "動(dòng)作"
},
{
"count": 22094,
"name": "喜劇"
},
{
"count": 14424,
"name": "香港"
},
{
"count": 9839,
"name": "冒險(xiǎn)"
},
{
"count": 8222,
"name": "2012"
},
{
"count": 7660,
"name": "搞笑"
},
{
"count": 3214,
"name": "3D"
},
{
"count": 2524,
"name": "中國(guó)大陸"
}
],
"title": "十二生肖"
}
這個(gè)JSON數(shù)據(jù)可以說是非常復(fù)雜的怜森,考慮到了各種情況。數(shù)值部分有整數(shù)谤牡、浮點(diǎn)數(shù)副硅、字符串。JSON里面還嵌套有多個(gè)Dictionary和Array翅萤。
我們要轉(zhuǎn)換的Model定義如下:
// MovieAttrs
@interface DBMovieAttrs: MTLModel<MTLJSONSerializing>
@property (nonatomic, strong) NSArray * cast;
@property (nonatomic, strong) NSArray * country;
@property (nonatomic, strong) NSArray * director;
@property (nonatomic, strong) NSArray * language;
@property (nonatomic, strong) NSArray * movieDuration;
@property (nonatomic, strong) NSArray * movieType;
@property (nonatomic, strong) NSArray * pubdate;
@property (nonatomic, strong) NSArray * title;
@property (nonatomic, strong) NSArray * website;
@property (nonatomic, strong) NSArray * writer;
@property (nonatomic, strong) NSArray * year;
@end
// MovieAuthor
@interface DBMovieAuthor: MTLModel<MTLJSONSerializing>
@property (nonatomic, strong) NSString * name;
@end
// MovieRating
@interface DBMovieRating: MTLModel<MTLJSONSerializing>
@property (nonatomic, strong) NSNumber * average;
@property (nonatomic, assign) NSInteger max;
@property (nonatomic, assign) NSInteger min;
@property (nonatomic, assign) NSInteger numRaters;
@end
// MovieTag
@interface DBMovieTag: MTLModel<MTLJSONSerializing>
@property (nonatomic, assign) NSInteger count;
@property (nonatomic, strong) NSString * name;
@end
// Main
@interface DBMovie: MTLModel<MTLJSONSerializing>
@property (nonatomic, strong) NSURL * alt;
@property (nonatomic, strong) NSString * altTitle;
@property (nonatomic, strong) NSString * movieID;
@property (nonatomic, strong) NSURL * imageURL;
@property (nonatomic, strong) NSURL * mobileLinkURL;
@property (nonatomic, strong) NSString * summary;
@property (nonatomic, strong) NSString * title;
// ==== MovieAttrs
@property (nonatomic, strong) DBMovieAttrs * attrs;
// ==== DBMovieAuthor
@property (nonatomic, strong) NSArray * authors;
// ==== MovieRating
@property (nonatomic, strong) DBMovieRating * rating;
// ==== MovieTag
@property (nonatomic, strong) NSArray * tags;
@end
觀察DBMovie
中的imageURL
屬性恐疲,是一個(gè)NSURL
對(duì)象。這邊有點(diǎn)奇怪套么,JSON中是不包含特殊數(shù)據(jù)類型的啊培己。JSON里面確實(shí)沒有NSURL
,但是我們實(shí)際使用的時(shí)候肯定是用NSURL
胚泌,所以為了方便起見省咨,我們會(huì)在Model化的時(shí)候進(jìn)行一個(gè)轉(zhuǎn)換。而且玷室,通過Mantle這個(gè)強(qiáng)大的工具零蓉,我們可以很方便的進(jìn)行這個(gè)工作笤受。
MovieAttrs
、DBMovieAuthor
敌蜂、MovieRating
感论、MovieTag
都是類對(duì)象,都是通過對(duì)二級(jí)JSON對(duì)象的轉(zhuǎn)換得到的紊册。轉(zhuǎn)換方法同NSURL
類似比肄。
核心類
Mantle的核心類有3個(gè):
- MTLModel
- MTLJSONAdapter
- MTLJSONSerializing
MTLModel
MTLModel
是所有Model的父類,提供了一些默認(rèn)的行為來處理對(duì)象的初始化和歸檔操作囊陡,同時(shí)可以獲取到對(duì)象所有屬性的鍵值集合
MTLJSONAdapter
用于在MTLModel對(duì)象和JSON字典之間進(jìn)行相互轉(zhuǎn)換芳绩,相當(dāng)于是一個(gè)適配器
MTLJSONSerializing
需要與JSON字典進(jìn)行相互轉(zhuǎn)換的MTLModel的子類都需要實(shí)現(xiàn)該協(xié)議,以方便MTLJSONApadter對(duì)象進(jìn)行轉(zhuǎn)換
實(shí)現(xiàn)DBMovie
1 首先根據(jù)JSON數(shù)據(jù)定義寫好頭文件中的property.
@property (nonatomic, strong) NSURL * alt;
@property (nonatomic, strong) NSString * altTitle;
@property (nonatomic, strong) NSString * movieID;
@property (nonatomic, strong) NSURL * imageURL;
@property (nonatomic, strong) NSURL * mobileLinkURL;
@property (nonatomic, strong) NSString * summary;
@property (nonatomic, strong) NSString * title;
// ==== MovieAttrs
@property (nonatomic, strong) DBMovieAttrs * attrs;
// ==== DBMovieAuthor
@property (nonatomic, strong) NSArray * authors;
// ==== MovieRating
@property (nonatomic, strong) DBMovieRating * rating;
// ==== MovieTag
@property (nonatomic, strong) NSArray * tags;
2 寫好Model字段同JSON字段的映射
+ (NSDictionary *)JSONKeyPathsByPropertyKey {
return @{ @"alt" : @"alt",
@"altTitle" : @"alt_title",
@"movieID" : @"id",
@"imageURL" : @"image",
@"mobileLinkURL" : @"mobile_link",
@"summary" : @"summary",
@"title" : @"title",
@"attrs" : @"attrs",
@"authors" : @"author",
@"rating" : @"rating",
@"tags" : @"tags",
};
}
3 寫好特殊字段的處理方法回調(diào)函數(shù)
回調(diào)方法是根據(jù)特殊字段名稱來命名的撞反,例如imageURL這個(gè)字段妥色,它的函數(shù)名為:imageURLJSONTransformer
+ (NSValueTransformer *)imageURLJSONTransformer {
return [MTLValueTransformer valueTransformerForName:MTLURLValueTransformerName];
}
上面的例子使用了內(nèi)置的轉(zhuǎn)換功能MTLURLValueTransformerName
,實(shí)際上還有一個(gè)內(nèi)置的轉(zhuǎn)換功能MTLBooleanValueTransformerName
遏片。
除此之外嘹害,如果你要轉(zhuǎn)換一個(gè)你自己寫的類,那么就應(yīng)該是用自定義轉(zhuǎn)換吮便,比如我們要轉(zhuǎn)換attrs笔呀,它在Model中被映射為DBMovieAttrs
類型。
+ (NSValueTransformer *)attrsJSONTransformer {
return [MTLValueTransformer transformerUsingForwardBlock:^id(id value, BOOL *success, NSError *__autoreleasing *error) {
DBMovieAttrs * attrsModel = [MTLJSONAdapter modelOfClass:[DBMovieAttrs class] fromJSONDictionary:value error:nil];
return attrsModel;
}];
}
使用Mantle內(nèi)置的轉(zhuǎn)換函數(shù)+ (instancetype)transformerUsingForwardBlock:(MTLValueTransformerBlock)transformation
回調(diào)中的value是傳遞過來的值髓需,一般是一個(gè)Dictionary或者Array许师。返回一個(gè)對(duì)象,在這邊是DBMovieAttrs
的對(duì)象
4 寫好JSON 中null
值字段的處理方法回調(diào)
在JSON中僚匆,如果一個(gè)字段沒有值微渠,那么值是null
,我們?cè)诔绦蛑行枰厥馓幚硭掷蓿疫\(yùn)的是Mantle已經(jīng)為我們考慮好了逞盆。你只需要添加一個(gè)處理回調(diào)函數(shù),即可萬無一失松申。
- (void)setNilValueForKey:(NSString *)key {
[self setValue:@0 forKey:key]; // For NSInteger/CGFloat/BOOL
}
你可以根據(jù)key來設(shè)置不同的默認(rèn)值云芦。非常方便。
寫在后面
具體的實(shí)現(xiàn)代碼可以到這邊查看
https://github.com/irobbin1024/Mantle-DoubanMovie