項目中使用JSONModel解析接口返回時,遇到一個model對應多個接口字段,例如
A:
contacts = (
{
contactId = xx;
contactName = "xx";
},
{
contactId = xx;
contactName = "xx";
}
);
B:
contacts = (
{
id = xx;
name = "xxx";
},
{
id = xx;
name = "xx";
}
);
對應的model
@protocol MSContactModel;
@interface MSContactModel : JSONModel
@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) NSString *contactType;
@property (nonatomic, strong) NSString *cellphone;
@property (nonatomic, strong) NSString *telephone;
@property (nonatomic, strong) NSString *email;
@property (nonatomic, strong) NSString *contactId;
@end
.m
+(JSONKeyMapper *)keyMapper
{
NSMutableDictionary *keyMapper = [NSMutableDictionary dictionary];
[keyMapper setObject:@"id" forKey:@"contactId"];
[keyMapper setObject:@"name" forKey:@"contactName"];
return [[JSONKeyMapper alloc] initWithDictionary:keyMapper];
}
這樣會造成接口返回字段為name時,不能正確解析。
原因是
JSONModel.m
-(BOOL)__importDictionary:(NSDictionary*)dict withKeyMapper:(JSONKeyMapper*)keyMapper validation:(BOOL)validation error:(NSError**)err
{
//loop over the incoming keys and set self's properties
for (JSONModelClassProperty* property in [self __properties__]) {
//convert key name ot model keys, if a mapper is provided
NSString* jsonKeyPath = (keyMapper||globalKeyMapper) ? [self __mapString:property.name withKeyMapper:keyMapper importing:YES] : property.name;//這里會根據(jù)keyMapper返回
//JMLog(@"keyPath: %@", jsonKeyPath);
//general check for data type compliance
id jsonValue;
@try {
jsonValue = [dict valueForKeyPath: jsonKeyPath];
}
@catch (NSException *exception) {
jsonValue = dict[jsonKeyPath];
}
解決方法
JSONModel.m
-(BOOL)__importDictionary:(NSDictionary*)dict withKeyMapper:(JSONKeyMapper*)keyMapper validation:(BOOL)validation error:(NSError**)err
{
//loop over the incoming keys and set self's properties
for (JSONModelClassProperty* property in [self __properties__]) {
//convert key name ot model keys, if a mapper is provided
NSString*jsonKeyPath = nil;
//JMLog(@"keyPath: %@", jsonKeyPath);
//這里先判斷是否可以直接解析
if (dict[property.name]) {
jsonKeyPath = property.name;
}else{
jsonKeyPath = (keyMapper) ? [self __mapString:property.name withKeyMapper:keyMapper importing:YES] : property.name;
}
//general check for data type compliance
id jsonValue;
@try {
jsonValue = [dict valueForKeyPath: jsonKeyPath];
}
@catch (NSException *exception) {
jsonValue = dict[jsonKeyPath];
}
由于直接修改源碼會導致,更新pod的時候會被覆蓋,所以創(chuàng)建Category
JSONModel+Track
JSONModel+Track.m
...........
if (dict[property.name]) {
jsonKeyPath = property.name;
}else{
jsonKeyPath = (keyMapper) ? [self __mapString:property.name withKeyMapper:keyMapper importing:YES] : property.name;
}
...........
參考
Single Model with multiple KeyMappers for serializing
JSONModel命名中的駝峰(CamelCase)與下劃線 (UnderscoreCase)