测试已测试 | ✓ |
Lang语言 | Obj-CObjective C |
许可证 | MIT |
发布最后发布 | 2014年12月 |
由 Cocoapods Admin,Duncan Lewis,Prachi Gauriar 维护。
TWTValidation 是一个用于声明性验证数据的 Cocoa 框架。它提供了一种验证单一对象和集合,并通过使用逻辑运算符组合多个验证器来创建更复杂的验证的机制。
TWTValidation 1.1 添加了多个新验证器和更新了现有验证器以变得更加灵活。
TWTValueSetValidator
验证值是否在有效值的集合中。TwTPrefixStringValidator
确保字符串有给定的前缀。TwTSuffixStringValidator
确保字符串有给定的后缀。TWTSubstringStringValidator
验证字符串是否包含特定的子字符串。TWTWildcardPatternStringValidator
验证字符串是否匹配通配符模式。通配符模式支持使用 *
和 ?
通配符字符。TWTCharacterSetStringValidator
验证字符串仅包含给定字符集中的字符。TWTCollectionValidator
在尝试验证值之前检查值是否响应 -count
并遵守 NSFastEnumeration
协议。以前,如果值不符合那些标准,则会在 -validateValue:error:
中发生崩溃。TWTKeyedCollectionValidator
在尝试验证值之前检查值是否响应 -count
和 -objectForKey:
并遵守 NSFastEnumeration
协议。TWTNumberValidator
现在允许使用排他性的最小和最大值,分别验证值是否严格大于最小值或严格小于最大值。TWTKeyValueCodingValidator
现在在在使用 +twt_validatorsForKey
之前会尝试使用 -twt_validatorsForKey:
来获取键的验证器。这可以实现基于实例状态的动态验证器。有关更多信息,请参阅类文档。userInfo
字典中。可以使用 -[NSError twt_failingValidator]
来检索。开始使用TWTValidation的最简单方法是通过CocoaPods安装它。
pod 'TWTValidation', '~> 1.1'
您也可以构建它,并在项目中包含构建的产品。对于OS X,只需将TWTValidation.framework
添加到您的项目中。对于iOS,向您的头文件搜索路径中添加TWTValidation的公共头文件,并链接libTWTValidation.a
,所有这些都可以在项目的构建输出目录中找到。
TWTValidation提供各种用例的验证器,但不会限制您如何使用它们。TWTValidation中的所有验证器都继承自TWTValidator
,这是一个抽象类,它声明了验证器的核心接口-validateValue:error:
。此方法验证指定的值并返回它是否通过验证。如果值未能验证,则通过错误参数间接返回描述验证失败原因的错误。
让我们依次讨论TWTValidator
的主要子类的每一个。这些都仅是可能性的概述。有关更详细的信息,请查看每个类的头文件中的文档。
值验证器继承自TWTValueValidator
。本身,TWTValueValidator
只能执行一些基本的验证:它可以选择确保值是特定类的一个实例,不是null
NSNull实例。
TWTValueValidator *validator = [TWTValueValidator valueValidatorWithClass:[NSNumber class]
allowsNil:NO
allowsNull:YES];
NSError *error = nil;
[validator validateValue:@10 error:&error]; // Returns YES
[validator validateValue:[NSNull null] error:&error]; // Returns YES
[validator validateValue:@"foo" error:&error]; // Returns NO
[validator validateValue:nil error:&error]; // Returns NO
通过TWTValueValidator
的子类TWTStringValidator
和TWTNumberValidator
执行更有用的验证。字符串验证器可以验证值是否为字符串并且具有给定的前缀或后缀;包含给定的子字符串;匹配指定的通配符模式或正则表达式;或者具有指定范围内的长度。
NSRegularExpression *regEx = [[NSRegularExpression alloc] initWithPattern:@"^[A-Z][a-z]+$"
options:0
error:NULL];
NSError *error = nil;
TWTStringValidator *validator = [TWTStringValidator stringValidatorWithRegularExpression:regEx
options:0];
[validator validateValue:@"Uppercase" error:&error]; // Returns YES
[validator validateValue:@"lowercase" error:&error]; // Returns NO
validator = [TWTStringValidator stringValidatorWithMinimumLength:4 maximumLength:10];
[validator validateValue:@"Foobar" error:&error]; // Returns YES
[validator validateValue:@"Foo" error:&error]; // Returns NO
validator = [TWTStringValidator stringValidatorWithPrefix:@"foob" caseSensitive:NO];
[validator validateValue:@"Foobar" error:&error]; // Returns YES
[validator validateValue:@"Foo" error:&error]; // Returns NO
validator = [TWTStringValidator stringValidatorWithSuffix:@"oo" caseSensitive:YES];
[validator validateValue:@"Foobar" error:&error]; // Returns NO
[validator validateValue:@"Foo" error:&error]; // Returns YES
validator = [TWTStringValidator stringValidatorWithSubstring:@"OBA" caseSensitive:NO];
[validator validateValue:@"Foobar" error:&error]; // Returns YES
[validator validateValue:@"Foo" error:&error]; // Returns NO
validator = [TWTStringValidator stringValidatorWithPattern:@"*b*" caseSensitive:YES];
[validator validateValue:@"Foobar" error:&error]; // Returns YES
[validator validateValue:@"Foo" error:&error]; // Returns NO
validator = [TWTStringValidator stringValidatorWithCharacterSet:[NSCharacterSet letterCharacterSet]];
[validator validateValue:@"Foobar" error:&error]; // Returns YES
[validator validateValue:@":)" error:&error]; // Returns NO
数字验证器确保一个数字在某个范围内,并可选择没有小数部分。
TWTNumberValidator *validator = [[TWTNumberValidator alloc] initWithMinimum:@10 maximum:@20];
NSError *error = nil;
[validator validateValue:@15.333 error:&error]; // Returns YES
[validator validateValue:@3 error:&error]; // Returns NO
validator.exclusiveMinimum = YES;
[validator validateValue:@10 error:&error]; // Returns NO
validator.requiresIntegralValue = YES;
[validator validateValue:@15.333 error:&error]; // Returns NO
TWTCompoundValidator
实例或简称为复合验证器,允许您使用逻辑运算符(如AND、OR和NOT)组合验证器。
TWTNumberValidator *rangeValidator = [TWTNumberValidator numberValidatorWithMinimum:@2 maximum:@10];
TWTCompoundValidator *notValidator = [TWTCompoundValidator notValidatorWithSubvalidator:rangeValidator];
NSError *error = nil;
[notValidator validateValue:@3 error:&error]; // Returns NO
[notValidator validateValue:@0.123 error:&error]; // Returns YES
[notValidator validateValue:@"foo" error:&error]; // Returns YES, :-(
TWTNumberValidator *numberValidator = [[TWTNumberValidator alloc] init];
NSArray *subvalidators = @[ numberValidator, notValidator ];
TWTCompoundValidator *andValidator = [TWTCompoundValidator andValidatorWithSubvalidators:subvalidators];
[andValidator validateValue:@3 error:&error]; // Returns NO
[andValidator validateValue:@0.123 error:&error]; // Returns YES
[andValidator validateValue:@"foo" error:&error]; // Returns NO, :-)
TWTNumberValidator *integralValidator = [rangeValidator copy];
integralValidator.requiresIntegralValue = YES;
subvalidators = @[ andValidator, integralValidator ];
TWTCompoundValidator *orValidator = [TWTCompoundValidator orValidatorWithSubvalidators:subvalidators];
[orValidator validateValue:@3 error:&error]; // Returns YES
[orValidator validateValue:@7.33 error:&error]; // Returns NO
[orValidator validateValue:@0 error:&error]; // Returns YES
[orValidator validateValue:@"foo" error:&error]; // Returns NO
TWTBlockValidator
允许您指定一个块来执行任意的验证。
TWTBlockValidator *validator = [[TWTBlockValidator alloc] initWithBlock:^BOOL(id value, NSError **error) {
BOOL validated = [value isKindOfClass:[NSNumber class]] && value.integerValue % 2 == 0;
if (!validated && error) {
*error = [NSError twt_validationErrorWithCode:5
value:value
localizedDescription:NSLocalizedString(@"Value is not in set", nil)];
}
return validated;
}];
NSError *error = nil;
[validator validateValue:@"value1" error:&error]; // Returns YES
[validator validateValue:@"value4" error:&error]; // Returns NO
您可以使用TWTCollectionValidator
实例来验证集合的计数和元素。集合验证器使用快速枚举来获取集合的元素。因此,它主要用于验证数组、集合和有序集合。但是,它可以与实现NSFastEnumeration
并响应-count
的任何对象一起工作。
TWTNumberValidator *countValidator = [[TWTNumberValidator alloc] initWithMinimum:@1 maximum:@3];
NSRegularExpression *regEx = [[NSRegularExpression alloc] initWithPattern:@"^[A-Z][a-z]+$"
options:0
error:NULL];
NSArray *elementValidators = @[ [TWTStringValidator stringValidatorWithRegularExpression:regEx
options:0] ];
TWTCollectionValidator *validator =
[[TWTCollectionValidator alloc] initWithCountValidator:countValidator
elementValidators:elementValidators];
NSError *error = nil;
id collection = [NSSet setWithObjects:@"Apple", @"Pear", @"Orange", nil];
[validator validateValue:collection error:&error]; // Returns YES
collection = @[ @"Apple", @"Pear", @"orange" ];
[validator validateValue:collection error:&error]; // Returns NO
collection = [NSOrderedSet orderedSetWithObjects:@"Apple", @"Pear", @"Orange", @"Grape", nil];
[validator validateValue:collection error:&error]; // Returns NO
要验证字典和映射表,请使用TWTKeyedCollectionValidator
。这些验证器可以验证键值集合的计数、键和值,以及特定的键值对。
TWTNumberValidator *countValidator = [[TWTNumberValidator alloc] initWithMinimum:@1 maximum:@3];
TWTStringValidator *keyValidator = [[TWTStringValidator alloc] init];
TWTStringValidator *valueValidator = [[TWTNumberValidator alloc] init];
TWTNumberValidator *ageValidator = [[TWTNumberValidator alloc] initWithMinimum:@0 maximum:@130];
TWTKeyValuePairValidator *agePairValidator = [[TWTKeyValuePairValidator alloc] initWithKey:@"age"
valueValidator:ageValidator]
TWTKeyedCollectionValidator *validator =
[[TWTKeyedCollectionValidator alloc] initWithCountValidator:countValidator
keyValidators:@[ keyValidator ]
valueValidators:@[ valueValidator ]
keyValuePairValidators:@[ agePairValidator ]];
NSError *error = nil;
id collection = @{ @"key1" : @1 };
[validator validateValue:collection error:&error]; // Returns YES
collection = @{ @"key1" : @1, @"key2" : @2, @"key3" : @3, @"key4" : @4 };
[validator validateValue:collection error:&error]; // Returns NO
collection = @{ @1 : @2 };
[validator validateValue:collection error:&error]; // Returns NO
collection = @{ @"key1" : @"value1" };
[validator validateValue:collection error:&error]; // Returns NO
collection = @{ @"key1" : @1, @"key2" : @2, @"age" : @11 };
[validator validateValue:collection error:&error]; // Returns YES
collection = @{ @"key1" : @1, @"key2" : @2, @"age" : @-3 };
[validator validateValue:collection error:&error]; // Returns NO
在TWTValidation中,最有趣和有用的验证器可能是键值编码验证器。这些对象是TWTKeyValueCodingValidator
的实例,用于验证对象针对一组符合键值编码规范的关键字值的认证。它从对象的类中获取用于每个键的验证器,与键值观察以获取影响关键字键的键路径的方式几乎相同。以下是一个示例,这最好地解释了这一点。
// Header File
@interface TWTSimplePerson : NSObject
@property (nonatomic, copy) NSString *firstName;
@property (nonatomic, copy) NSString *lastName;
@property (nonatomic, strong) NSNumber *age;
- (BOOL)isValid;
@end
// Implementation File
#import <TWTValidation/TWTValidation.h>
@interface TWTSimplePerson ()
@property (nonatomic, strong) TWTKeyValueCodingValidator *validator;
@end
@implementation TWTSimplePerson
- (instancetype)init
{
self = [super init];
if (self) {
NSSet *keys = [NSSet setWithObjects:@"firstName", @"lastName", @"age", nil];
_validator = [[TWTKeyValueCodingValidator alloc] initWithKeys:keys];
}
return self;
}
- (BOOL)isValid
{
return [self.validator validateValue:self error:NULL];
}
// Key-value coding validators get the validators for their KVC keys by invoking -twt_validatorsForKey:
// and +twt_validatorsForKey: on the value’s class. The base implementations of those methods simply check
// to see if the class implements -twt_validatorsFor«Key» and +twt_validatorsFor«Key», where «Key» is the
// capitalized form of the KVC key. When you have multiple keys that use the same validators, you can override
// this implementation. Here, we return the same validators for firstName and lastName, but rely on the
// superclass implementation to invoke -twt_validatorsForAge to get the validators for the age key.
+ (NSSet *)twt_validatorsForKey:(NSString *)key
{
if ([key isEqualToString:@"firstName"] || [key isEqualToString:@"lastName"]) {
return [NSSet setWithObject:[TWTStringValidator stringValidatorWithMinimumLength:1 maximumLength:20]];
}
return [super twt_validatorsForKey:key];
}
- (NSSet *)twt_validatorsForAge
{
return [NSSet setWithObject:[[TWTNumberValidator alloc] initWithMinimum:@0 maximum:@130]];
}
@end
要详细了解如何使用键值编码验证器,请参阅我们的示例项目。
如果TWTValidation中的验证器不能满足您的需求,添加新验证器或扩展现有验证器都非常简单。只需继承TWTValidator
或其子类之一,并重写‑validateValue:error:
方法。查看任何一个TWTValidator
子类可以获得更多指导。我们还在TWTValidationErrors.h
中提供了一些构建错误对象的方法,以便参考。
如果您希望帮助修复错误或向TWTValidation添加功能,请向我们发送拉取请求!
我们使用GitHub问题跟踪错误、增强功能请求和支持,因此为上述任一项打开问题。
所有代码均受MIT许可证许可。您可以自由使用。