您如何使用键值验证?

时间:2013-10-16 21:32:23

标签: ios objective-c

有人可以告诉我如何在IOS中使用键值验证吗?我很困惑。

我正在编写Payments SDK,人们将信用卡号,安全码等传递给Card类,我需要验证这些值。例如,确保信用卡号有效。

是否可以进行自动验证?

另外,我们可以立即调用所有验证器吗?

如果我有一个Card类,我可以调用if([card isValid])来一次调用所有验证函数而不是自己调用吗? 像:

Card * card = [[Card alloc] init];
card.number = @"424242...";
card.securityCode = @"455";
card.expirationMonth = @"";
card.expirationYear = @"";
if([card isValid]) {

感谢您的帮助!

3 个答案:

答案 0 :(得分:6)

Susan提供的链接包含您应该需要的所有细节。示例实现如下:

- (BOOL)validateSecurityCode:(id *)ioValue 
                       error:(NSError * __autoreleasing *)outError 
{
    // The securityCode must be a numeric value exactly 3 digits long
    NSString *testValue = (NSString *)*ioValue;
    if (([testValue length]!=3) || ![testValue isInteger])) {
        if (outError != NULL) {
            NSString *errorString = NSLocalizedString(
                    @"A Security Code must be exactly 3 characters long.",
                    @"validation: Security Code, invalid value");
            NSDictionary *userInfoDict = @{ NSLocalizedDescriptionKey : errorString };
            *outError = [[NSError alloc] initWithDomain:SECURITYCODE_ERROR_DOMAIN
                                                   code:SECURITYCODE_INVALID_NAME_CODE
                                               userInfo:userInfoDict];
        }
        return NO;
    }
    return YES;
}

注意:我使用了来自this postNSString -isInteger

手册说

  

您可以直接调用验证方法,也可以调用 validateValue:forKey:error:并指定密钥。

这样做的好处是您的- (BOOL)isValid方法非常简单。

- (BOOL)isValid
{
    static NSArray *keys = nil;
    static dispatch_once_t once;
    dispatch_once(&once, ^{
        keys = @[@"securityCode", @"number", @"expirationMonth", @"expirationYear"];
    });

    NSError *error = nil;
    for (NSString *aProperty in keys) {
        BOOL valid = [self validateValue:[self valueForKey:aProperty]
                                  forKey:aProperty
                                   error:&error];
        if (!valid) {
            NSLog("Validation Error: %@", error);
            return NO;
        }
    }
    return YES;
}

答案 1 :(得分:2)

以下是键值验证的示例。

根据Apple的说法:

键值编码为验证属性值提供了一致的API。验证基础结构为类提供了接受值,提供备用值或拒绝属性的新值并给出错误原因的机会。

https://developer.apple.com/library/mac/documentation/cocoa/conceptual/KeyValueCoding/Articles/Validation.html

方法签名

-(BOOL)validateName:(id *)ioValue error:(NSError * __autoreleasing *)outError {
    // Implementation specific code.
    return ...;
}

正确调用方法

苹果: 您可以直接调用验证方法,或者通过调用validateValue:forKey:error:并指定密钥。

我们的:

//Shows random use of this
    -(void)myRandomMethod{

        NSError *error;

        BOOL validCreditCard = [self validateCreditCard:myCreditCard error:error];
    }

我们对您的请求的测试实施

    //Validate credit card
    -(BOOL)validateCreditCard:(id *)ioValue error:(NSError * )outError{

        Card *card = (Card*)ioValue;

        //Validate different parts
        BOOL validNumber = [self validateCardNumber:card.number error:outError];
        BOOL validExpiration = [self validateExpiration:card.expiration error:outError];
        BOOL validSecurityCode = [self validateSecurityCode:card.securityCode error:outError];

        //If all are valid, success
        if (validNumber && validExpiration && validSecurityCode) {
            return YES;

            //No success
        }else{
            return NO;
        }
    }

    -(BOOL)validateExpiration:(id *)ioValue error:(NSError * )outError{

        BOOL isExpired = false;

        //Implement expiration

        return isExpired;
    }

    -(BOOL)validateSecurityCode:(id *)ioValue error:(NSError * )outError{

    //card security code should not be nil and more than 3 characters long
    if ((*ioValue == nil) || ([(NSString *)*ioValue length] < 3)) {

        //Make sure error us not null
        if (outError != NULL) {

            //Localized string
            NSString *errorString = NSLocalizedString(
                                                      @"A card's security code must be at least three digits long",
                                                      @"validation: Card, too short expiration error");

            //Place into dict so we can add it to the error
            NSDictionary *userInfoDict = @{ NSLocalizedDescriptionKey : errorString };

            //Error
            *outError = [[NSError alloc] initWithDomain:CARD_ERROR_DOMAIN
                                                   code:CARD_INVALID_SECURITY_CODE
                                               userInfo:userInfoDict];
        }
        return NO;
    }
    return YES;
}

    -(BOOL)validateCardNumber:(id *)ioValue error:(NSError * )outError{

        BOOL isValid = false;

        //Implement card number verification

        return isValid;
    }

答案 2 :(得分:0)

键值编码(KVC)验证用于验证要放入特定属性的单个值。它不是自动的,您应该never invoke a validation method within the -set accessor获取属性。预期用途(至少我在Apple样本中使用它或自己使用它的方式)是在变异对象之前验证来自用户的输入。在使用Cocoa Bindings的Mac OSX应用程序上,这非常有用,但在iOS上并没有那么多。

我不相信您正在寻找KVC验证,因为您要检查所有对象属性值是否有效。正如其他人发布的那样,你可以让它发挥作用,但它会增加复杂性而没有任何显着的好处。