準(zhǔn)備:
JSONModel
快速的解析數(shù)據(jù)為Model模型,支持層級嵌套Model模型解析,指定類型自動轉(zhuǎn)化,無需手動解析,一行代碼搞定!
配合ESJsonFormat插件效果更佳!
ESJSONFormatter_下載
配合ESJsonFormat效果更佳
基本使用
假設(shè)你的 JSON 串像下面這樣子:
{
"id":"10",
"country":"Germany",
"dialCode": 49,
"isInEurope":true
}
創(chuàng)建一個你自己的類,并繼承至 JSONModel
在你的頭文件里面進行聲明你所需要的 JSON key值
#import "JSONModel.h"
@interface CountryModel : JSONModel
@property (assign, nonatomic) int id;
@property (strong, nonatomic) NSString* country;
@property (strong, nonatomic) NSString* dialCode;
@property (assign, nonatomic) BOOL isInEurope;
@end
.m文件中你不需要做其他的事情了.
初始化你的 model ,如下所示:
#import "CountryModel.h"
...
NSString* json = (fetch here JSON from Internet) ...
NSError* err = nil;
CountryModel* country = [[CountryModel alloc] initWithString:json error:&err];
如果傳過來的 JSON 合法,你所定義的所有的屬性都會與該 JSON 值相匹配,并且 JSONModel 也會嘗試盡可能的轉(zhuǎn)換成你所想要的數(shù)據(jù),就像上面的例子:
- 轉(zhuǎn)化 "id",從字符串轉(zhuǎn)換成 int 型
- 拷貝 country 屬性的值
- 轉(zhuǎn)換 dialCode ,從NSNumber 轉(zhuǎn)換為 NSString 值
- 最后一個呢是將 isInEurope 轉(zhuǎn)換成 BOOL 的屬性
所以,你需要做的就是定義出你期望的屬性就行了。
例子
<u>例子中所有Model模型都要繼承JSONModel</u>
1.命名自動匹配
- Model屬性名和服務(wù)器返回數(shù)據(jù)字段一致
命名自動匹配
2.Model關(guān)聯(lián)(model含有其他model)
- Model屬性名和服務(wù)器返回數(shù)據(jù)字段一致
- 關(guān)聯(lián)其他Model的屬性需要指定自身類型(例如: <u>ProductModel</u>*)
Model關(guān)聯(lián)
3.Model集合(model含有其他model的集合)
注意:
NSArry后的就<>中包含一個協(xié)議,這并不是Objective-C的新語法,他們不會沖突,使用JSONModel必須實現(xiàn)這個協(xié)議!
層級嵌套,Model中包含其他Model集合,必須實現(xiàn)該協(xié)議!!!
@protocol 協(xié)議必須實現(xiàn)!!!(如下圖所示)
- 包含其他Model集合的屬性需要指定層級類型和自身類型(例如: <u>NSArray<ProductModel></u>*)
Model集合
4.鍵映射
- 在一個Model中獲取服務(wù)器返回數(shù)據(jù)不同層級的數(shù)據(jù)
- 例如:order_id和name不在同一層級
- 采用KVC的方式來取值,并賦值給Model屬性(order_details.name ---> productName order_details.price.usd ---> price)
鍵映射
5.設(shè)置全局鍵映射(應(yīng)用于所有model)
全局鍵映射
6.設(shè)置下劃線自動轉(zhuǎn)駝峰
- 自定義把下劃線字段解析為駝峰命名屬性
- 場景:服務(wù)器數(shù)據(jù)返回下劃線命名字段可為Model中以駝峰命名的屬性相應(yīng)的賦值
- mapperFromUpperCaseToLowerCase 大寫轉(zhuǎn)小寫
下劃線自動轉(zhuǎn)駝峰
7.可選屬性(屬性值可以為空或null)
- 某些屬性值可以為空
- 防止由于服務(wù)器數(shù)據(jù)返回空導(dǎo)致JSONModel異常(程序崩潰)
可選屬性
8.忽略屬性(屬性值可以完全忽略)
- 解析時會完全忽略它
- 場景: 該屬性值不需要從服務(wù)器數(shù)據(jù)中獲取
忽略屬性
9.設(shè)置所有屬性可選(所有屬性值可以為空)
- Model的所有屬性值都可以為空
- 防止由于服務(wù)器數(shù)據(jù)返回空導(dǎo)致JSONModel異常(程序崩潰)
- 官方建議盡量避免使用該方法
所有屬性可選
10.使用內(nèi)置的HTTP鏈接
//添加額外的頭
[[JSONHTTPClient requestHeaders] setValue:@"MySecret" forKey:@"AuthorizationToken"];
//設(shè)置GET,POST請求
[JSONHTTPClient postJSONFromURLWithString:@"http://mydomain.com/api"
params:@{@"postParam1":@"value1"}
completion:^(id json, JSONModelError *err) {
//檢查錯誤,處理JSON
}];
11.將Model導(dǎo)出字典或JOSN字符串
- 快速導(dǎo)出Model中所有屬性和屬性值
ProductModel* pm = [[ProductModel alloc] initWithString:jsonString error:nil];
pm.name = @"Changed Name";
//以字典形式導(dǎo)出
NSDictionary* dict = [pm toDictionary];
//以字符串形式導(dǎo)出
NSString* string = [pm toJSONString];
12.自定義數(shù)據(jù)處理
- 添加NSDate轉(zhuǎn)換:根據(jù)后臺返回時間戳格式進行相應(yīng)處理
- 場景:內(nèi)嵌轉(zhuǎn)換,不能滿足需求,需要自定義
- JSONModel支持類型:
json支持類型
@implementation JSONValueTransformer (CustomTransformer)
//時間戳轉(zhuǎn)NSDate
- (NSDate *)NSDateFromNSString:(NSString*)string {
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:APIDateFormat];
return [formatter dateFromString:string];
}
//NSDate轉(zhuǎn)時間戳
- (NSString *)JSONObjectFromNSDate:(NSDate *)date {
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:APIDateFormat];
return [formatter stringFromDate:date];
}
@end
13.自定義處理特殊屬性
@interface ProductModel : JSONModel
@property (assign, nonatomic) int id;
@property (strong, nonatomic) NSString* name;
@property (assign, nonatomic) float price;
@property (strong, nonatomic) NSLocale *locale;
@end
@implementation ProductModel
//處理本地化標(biāo)識后給locale賦值
- (void)setLocaleWithNSString:(NSString*)string {
self.locale = [NSLocale localeWithLocaleIdentifier:string];
}
- (NSString *)JSONObjectForLocale {
return self.locale.localeIdentifier;
}
@end
14.自定義JSON驗證
@interface ProductModel : JSONModel
@property (assign, nonatomic) int id;
@property (strong, nonatomic) NSString* name;
@property (assign, nonatomic) float price;
@property (strong, nonatomic) NSLocale *locale;
@property (strong, nonatomic) NSNumber <Ignore> *minNameLength;
@end
@implementation ProductModel
- (BOOL)validate:(NSError *__autoreleasing *)error {
BOOL valid = [super validate:error];
if (self.name.length < self.minNameLength.integerValue) {
*error = [NSError errorWithDomain:@"me.mycompany.com" code:1 userInfo:nil];
valid = NO;
}
return valid;
}
@end
- 好的容錯能力
- 自定義數(shù)據(jù)鍵值匹配
- 自動比較以及判斷的特性