我有从MTLModel继承的MyModel(使用GitHub Mantle pod)。 MyModel.h
#import <Mantle/Mantle.h>
@interface MyModel : MTLModel <MTLJSONSerializing>
@property (nonatomic, copy, readonly) NSString *UUID;
@property (nonatomic, copy) NSString *someProp;
@property (nonatomic, copy) NSString *anotherProp;
@end
MyModel.m
#import "MyModel.h"
@implementation MyModel
+ (NSDictionary *)JSONKeyPathsByPropertyKey
{
return @{
@"UUID": @"id",
@"someProp": @"some_prop",
@"anotherProp": @"another"
};
}
}
@end
现在我想使用AFNetworking将JSON发送到后端。在此之前,我将模型实例转换为JSON NSDictionary,以在我的请求中用作参数/主体有效负载。
NSDictionary *JSON = [MTLJSONAdapter JSONDictionaryFromModel:myModel];
但是这个JSON包含奇怪的“”字符串,用于我的模型属性为零。我想要的是Mantle省略这些键/值对,只吐出一个只有非零或NSNull.null属性的JSON,无论如何。
答案 0 :(得分:37)
这是Mantle的一个常见问题,它被称为隐式JSON映射。
MTLJSONAdapter
读取模型的所有属性以创建JSON字符串,可选择用+JSONKeyPathsByPropertyKey
中给出的属性名称替换属性名称。
如果您希望从模型的JSON表示中排除某些属性,请将它们映射到NSNull.null
中的+JSONKeyPathsByPropertyKey
:
+ (NSDictionary *)JSONKeyPathsByPropertyKey {
return @{
@"UUID": @"id",
@"someProp": @"some_prop",
@"anotherProp": @"another",
@"myInternalProperty": NSNull.null,
@"myAnotherInternalProperty": NSNull.null,
};
}
隐式JSON映射最近成为一个值得注意的问题,目前正在GantHub的Mantle家庭存储库中讨论解决方案。
查看问题#137,#138,#143以及 #149 下的当前讨论。
编辑:我明显误解了这个问题,但现在,当我认为我理解正确时,答案很简单。
MTLJSONAdapter
使用MTLModel
的{{1}}属性生成JSON数据。如果您希望从JSON本身中排除某个属性,则可以在dictionaryValue
中覆盖该方法:
MYModel
编辑#2:查看代码*以删除- (NSDictionary *)dictionaryValue {
NSMutableDictionary *originalDictionaryValue = [[super dictionaryValue] mutableCopy];
if (self.aPropertyThatShouldBeExcludedWhenNil == nil) {
[originalDictionaryValue removeObjectForKey:@"aPropertyThatShouldBeExcludedWhenNil"];
}
/* repeat the process for other "hidden" properties */
return originalDictionaryValue;
}
的所有值:
nil
<子> - (NSDictionary *)dictionaryValue {
NSMutableDictionary *modifiedDictionaryValue = [[super dictionaryValue] mutableCopy];
for (NSString *originalKey in [super dictionaryValue]) {
if ([self valueForKey:originalKey] == nil) {
[modifiedDictionaryValue removeObjectForKey:originalKey];
}
}
return [modifiedDictionaryValue copy];
}
子>
答案 1 :(得分:1)
我通过创建 MTLJSONAdapter子类并覆盖-serializablePropertyKeys:forModel:
方法来删除无值键。
MTLJSONAdapterWithoutNil.h
/** A MTLJSONAdapter subclass that removes model dictionaryValue keys whose value is `[NSNull null]`. */
@interface MTLJSONAdapterWithoutNil : MTLJSONAdapter
@end
MTLJSONAdapterWithoutNil.m
#import "MTLJSONAdapterWithoutNil.h"
@implementation MTLJSONAdapterWithoutNil
- (NSSet *)serializablePropertyKeys:(NSSet *)propertyKeys forModel:(id<MTLJSONSerializing>)model {
NSMutableSet *ms = propertyKeys.mutableCopy;
NSDictionary *modelDictValue = [model dictionaryValue];
for (NSString *key in ms) {
id val = [modelDictValue valueForKey:key];
if ([[NSNull null] isEqual:val]) { // MTLModel -dictionaryValue nil value is represented by NSNull
[ms removeObject:key];
}
}
return [NSSet setWithSet:ms];
}
@end
并使用它来创建JSON字典。像这样:
NSDictionary *JSONDictionary = [MTLJSONAdapterWithoutNil JSONDictionaryFromModel:collection error:nil];
注意: 如果要覆盖数组或字典属性的NSValueTransformer
方法,还必须将MTLJSONAdapter
类更改为子类。< / strong>喜欢这个:
+ (NSValueTransformer *)myDailyDataArrayJSONTransformer {
return [MTLJSONAdapterWithoutNil arrayTransformerWithModelClass:KBDailyData.class];
}
答案 2 :(得分:0)
重写 - dictionaryValues没有给我预期的行为
所以我为MTL Base类创建了一个方法
- (NSDictionary *)nonNullDictionaryWithAdditionalParams:(NSDictionary *)params error:(NSError *)error {
NSDictionary *allParams = [MTLJSONAdapter JSONDictionaryFromModel:self error: &error];
NSMutableDictionary *modifiedDictionaryValue = [allParams mutableCopy];
for (NSString *originalKey in allParams) {
if ([allParams objectForKey:originalKey] == NSNull.null) {
[modifiedDictionaryValue removeObjectForKey:originalKey];
}
}
[modifiedDictionaryValue addEntriesFromDictionary:params];
return [modifiedDictionaryValue copy];
}
答案 3 :(得分:-1)
编辑#2过去常常使用之前的Mantle代码库。现在我必须执行以下操作继续使用EDIT#2:
在文件MTLJSONAdapter.m中,替换此行:
NSDictionary *dictionaryValue = [model.dictionaryValue dictionaryWithValuesForKeys:propertyKeysToSerialize.allObjects];
与
NSDictionary *dictionaryValue = model.dictionaryValue;
以上是我目前的解决方法
{ }
而不是
{
"AddressLine2" : null,
"City" : null,
"ZipCode" : null,
"State" : null,
"AddressLine1" : null
}