在返回对象之前验证每个属性

时间:2014-04-25 11:04:47

标签: ios objective-c github-mantle

在使用Mantle时,是否有可能在返回我们正在创建的对象之前(在这种情况下通过JSON)来验证X和Y属性是否为nil?

想象一下这个课程:

@interface Person : MTLModel <MTLJSONSerializing>

@property(nonatomic,strong,readonly)NSString *name;
@property(nonatomic,strong,readonly)NSString *age;

@end

我想要一种方法来验证如果我收到的JSON没有name(由于某种原因在服务器的数据库上存在问题)我会返回一个nil人,因为它没有该属性集创建该对象没有意义。

5 个答案:

答案 0 :(得分:3)

虽然您可以覆盖初始化程序。覆盖validate:似乎更简洁,因为在Mantle返回反序列化对象之前的最后一个阶段调用它。将所有验证逻辑放在validate方法中是有意义的......

查看MTLJSONAdapter

的最后一行
id model = [self.modelClass modelWithDictionary:dictionaryValue error:error];
return [model validate:error] ? model : nil;

这告诉我们,如果我们的自定义模型从NO返回validate,那么Mantle将丢弃该对象。

所以你可以在子类中执行以下操作:

- (BOOL)validate:(NSError **)error {
    return [super validate:error] && self.name.length > 0; 
}

理想情况下,在您自己的实现中,您可能希望返回适当的错误。

然后,验证方法将为您在validateValue:forKey:error:中使用Mantle注册的每个属性调用Foundation的JSONKeyPathsByPropertyKey。因此,如果您想要更加可控的验证设置,您还可以在此处验证您的数据..

答案 1 :(得分:1)

您可以使用MTLJSONSerializing协议方法classForParsingJSONDictionary:返回nil而不是无效对象:

// In your MTLModelSubclass.m
//
+ (Class)classForParsingJSONDictionary:(NSDictionary *)JSONDictionary {
    if (JSONDictionary[@"name"] == nil || JSONDictionary[@"age"] == nil) {
        return nil;
    }
    return self.class;
}

答案 2 :(得分:0)

事实上我并没有使用Mantle,但为了验证,我使用了另一个名为RPJSONValidator的GitHub库

它告诉您您期望的类型以及该值到达的类型。

一个简单的示例代码

NSError *error;

[RPJSONValidator validateValuesFrom:json
                   withRequirements:@{
                           @"phoneNumber" : [RPValidatorPredicate.isString lengthIsGreaterThanOrEqualTo:@7],
                           @"name" : RPValidatorPredicate.isString,
                           @"age" : RPValidatorPredicate.isNumber.isOptional,
                           @"weight" : RPValidatorPredicate.isString,
                           @"ssn" : RPValidatorPredicate.isNull,
                           @"height" : RPValidatorPredicate.isString,
                           @"children" : RPValidatorPredicate.isArray,
                           @"parents" : [RPValidatorPredicate.isArray lengthIsGreaterThan:@1]
                   } error:&error];

if(error) {
    NSLog(@"%@", [RPJSONValidator prettyStringGivenRPJSONValidatorError:error]);
} else {
    NSLog(@"Woohoo, no errors!");
}

每个键值对都描述了每个JSON值的要求。例如,键值对@"name"RPValidatorPredicate.isString将使用键&#34; name&#34;对JSON值发出一个要求。成为NSString。我们也可以链接要求。例如,@"age"RPValidatorPredicate.isNumber.isOptional会对&#34; age&#34;的值产生要求。成为NSNumber,但前提是它存在于JSON中。

答案 3 :(得分:0)

我使用的是旧版本的地幔。 YMMV

您可以覆盖 [MTLModel modelWithExternalRepresentation] 选择器。确保调用 [super modelWithExternalRepresentation] ,然后添加自己的代码以检查验证数据。

答案 4 :(得分:0)

我跟着曼特尔开了一个小issue

- (instancetype)initWithDictionary:(NSDictionary *)dictionaryValue error:(NSError *__autoreleasing *)error
{
    BOOL isValid = NO;
    if (self = [super initWithDictionary:dictionaryValue error:error])
    {
        isValid = ...
    }

    return isValid?self:nil;
}

所以最后只是覆盖:

- (instancetype)initWithDictionary:(NSDictionary *)dictionaryValue error:(NSError *__autoreleasing *)error