10

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

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

是否可以进行自动验证?

另外,我们可以一次调用所有的验证器吗?

就像我有一个 Card 类一样,我可以调用 if([card isValid]) 来一次调用所有验证函数而不自己这样做吗?喜欢:

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

谢谢你的帮助!

4

3 回答 3

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;
}

注意:我NSString -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;
}
于 2013-10-20T13:06:13.697 回答
2

这是键值验证的示例。

据苹果称:

键值编码为验证属性值提供了一致的 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 ...;
}

正确调用方法

Apple:您可以直接调用验证方法,或者通过调用 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;
    }
于 2013-10-20T13:31:02.113 回答
0

键值编码 (KVC) 验证用于验证要放入特定属性中的单个值。它不是自动的,您永远不应该在属性的访问器中调用验证方法。-set预期用途(至少我在 Apple 示例中看到它或我自己使用它的方式)是在改变你的对象之前验证用户的输入。在带有 Cocoa Bindings 的 Mac OSX 应用程序上,这非常有用,但在 iOS 上就没有那么多了。

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

于 2013-10-20T13:48:43.243 回答