如何使用Mantle省略JSON字典中的空值?

mat*_*ths 17 ios github-mantle

我有从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
Run Code Online (Sandbox Code Playgroud)

MyModel.m

#import "MyModel.h"
@implementation MyModel
+ (NSDictionary *)JSONKeyPathsByPropertyKey
{
        return @{
            @"UUID": @"id",
            @"someProp": @"some_prop",
            @"anotherProp": @"another"
    };
}
}
@end
Run Code Online (Sandbox Code Playgroud)

现在我想使用AFNetworking将JSON发送到后端.在此之前,我将模型实例转换为JSON NSDictionary,以在我的请求中用作参数/主体有效负载.

NSDictionary *JSON = [MTLJSONAdapter JSONDictionaryFromModel:myModel];
Run Code Online (Sandbox Code Playgroud)

但是这个JSON包含奇怪的""字符串,用于我的模型属性为零.我想要的是Mantle省略这些键/值对,只吐出一个只有非nil或NSNull.null属性的JSON,无论如何.

aka*_*kyy 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,
    };
}
Run Code Online (Sandbox Code Playgroud)

隐式JSON映射最近成为一个值得注意的问题,目前正在Mantle的GitHub主存储库中讨论解决方案.

请参阅问题#137,#138,#143#149下的当前讨论.


编辑:我明显误解了这个问题,但现在,当我想我理解正确时,答案很简单.

MTLJSONAdapter使用MTLModel's dictionaryValue属性生成JSON数据.如果您希望从JSON本身中排除属性,可以在以下内容中覆盖该方法MYModel:

- (NSDictionary *)dictionaryValue {
    NSMutableDictionary *originalDictionaryValue = [[super dictionaryValue] mutableCopy];

    if (self.aPropertyThatShouldBeExcludedWhenNil == nil) {
        [originalDictionaryValue removeObjectForKey:@"aPropertyThatShouldBeExcludedWhenNil"];
    }

    /* repeat the process for other "hidden" properties */

    return originalDictionaryValue;
}
Run Code Online (Sandbox Code Playgroud)

编辑#2:检查代码*以删除所有值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];
}
Run Code Online (Sandbox Code Playgroud)

* - code sample suggested by matths.

  • 奇怪的是EDIT#2解决方案对我不起作用.从来没有调用dictionaryValue方法.我必须为每个可能为null的值使用值变换器. (2认同)