1. 程式人生 > >jsonmodel屬性名與系統命名衝突解決方案

jsonmodel屬性名與系統命名衝突解決方案

如今基本都是客戶端請求伺服器的模式,資料傳遞方式基本都使用JSON的字串方式。然而當我們獲取了伺服器發來的字串時,需要將其轉換成我們的資料模型。由於手動轉換程式碼的繁瑣,就有了一些自動化轉換的第三方開源庫。其中比較有名的有YYModelJSONModelMantleMJExtension。今天主要說明的是JSONModel的原始碼。

JSONModel的使用

首先,如果想使用JSONModel ,必須自己的類必須繼承JSONModel.

其中常用的方法有如下:

例如: 一個RecipeModel 繼承JSONModel ,其有如下屬性

@interface RecipeModel : JSONModel
@property(nonatomic,copy) NSString * createDate; //create_date  不適合我們用 改為 createDate (去掉下劃線並將下劃線的第一個字母大寫)
@property(nonatomic,copy) NSString * Description; // description 與系統關鍵字衝突  改為 Description
@property(nonatomic,copy) NSString * favorite;
@property(nonatomic,copy) NSString * ID; // id 與系統關鍵字衝突 改為 ID
@property(nonatomic,copy) NSString * image;
// 模型中巢狀陣列, 陣列中存放另一種模型的物件
@property(nonatomic,strong) NSMutableArray * tagsInfo;  // 模型中有一個數組(數組裡每一元素又是另外一個模型 例如:TagsInfoModel)
@end
TagsInfoModel的屬性
@property (nonatomic, copy) NSString * ID;
@property (nonatomic, copy) NSString * text;
@property (nonatomic, copy) NSString * type;
現在問題來了:
(1) 當字典中的key 名 和 屬性名不一致時(例如 id , description), 通過實現這個方法, 設定賦值對應關係
+ (JSONKeyMapper *)keyMapper{
    // 屬性名作為key ,字典中的key名 作為 value
    return [[JSONKeyMapper alloc]initWithModelToJSONDictionary:@{@"createDate":@"create_date",@"Description":@"description",@"ID":@"id",@"tagsInfo":@"tags_info"}];
}
(2)字典中的key 值 個數少於模型屬性時, 導致key 和 屬性不匹配 屬性值為空的,會崩潰 ,需要忽略屬性,正常賦值
+(BOOL)propertyIsOptional:(NSString *)propertyName{
    return true;
}
(3) 解決模型中巢狀陣列的問題
- (instancetype)initWithDictionary:(NSDictionary *)dict error:(NSError *__autoreleasing *)err{
    self = [super initWithDictionary:dict error:err];
    // 走完 [super initWithDictionary:dict error:err] 之後, 除了tagsInfo 這個屬性之後, 其他的屬性都會被正常賦值, tagsInfo 的值是一個數組,陣列中存放的是字典物件; 但是我們希望tagsInfo 陣列中存放的是 TagsInfoModel 的物件, 所以需要進行特殊處理
    if (self) {
        // 現將 tagsInfo 物件的原陣列取出
        NSArray * array = dict[@"tags_info"];
        // 將陣列中的字典一個個的字典轉化為 TagsInfoModel 的物件
        self.tagsInfo = nil;
        NSError * error = nil;
        // 將一個個字典組成的陣列,轉化為物件(呼叫 arrayOfModelsFromDictionaries: 這個方法時, 實際上就是遍歷array 中的字典, 一個字典對應創建出一個TagsInfoModel 的物件, 並用字典的值給對應的屬性賦值)
        self.tagsInfo = [TagsInfoModel arrayOfModelsFromDictionaries:array error:&error];
    }
    return self;
}
(4)aa_bb ==> aaBb
+ (JSONKeyMapper *)keyMapper{
    return [JSONKeyMapper mapperFromUnderscoreCaseToCamelCase];
}
(5) 補充:方法(1) aa_bb ==> aaBb id ==> ID 等
- (void)setValue:(id)value forKey:(NSString *)key{
    if ([key isEqualToString:@"id"]) {
        [self setValue:value forKey:@"ID"];
    }else if([key isEqualToString:@"create_time"]){
        [self setValue:value forKey:@"createTime"];
    }
}
(6) 補充方法(2) 當屬性和字典中的key欄位 不一一對應,
- (void)setValue:(id)value forUndefinedKey:(NSString *)key{
    NSLog(@"忽略賦值的key = %@",key);
}
總結: 方法(1) 與方法(5) 實現其一就可以 ; 方法(2) 和方法(6)實現其一就可以