NGRValidator 是一个针对 iOS 和 OSX 的 Objective-C 第三方库。它允许您以您想要的方式验证数据。这是一种易于阅读、集中化和全面的解决方案,只需几行代码即可验证任何 Objective-C 模型。
通常,每个处理用户账户的项目都需要进行电子邮件验证。让我们一起看看如何进行
NSString *email = <#your string email address#>;
NSError *error = [NGRValidator validateValue:email named:@"E-mail address" rules:^(NGRPropertyValidator *validator) {
// 'is', 'to', 'have' are syntactic sugar and can be safely omitted
validator.is.required().to.have.syntax(NGRSyntaxEmail);
}];
代码太多?有更好的实现方式吗?如果想要验证密码呢?可以使用与上面类似的方法。然而,为了保持 MVC 模式,最好创建一个简单的具有验证功能的模型
@interface UserAccount : NSObject
//should have email syntax:
@property (strong, nonatomic) NSString *email;
//should have at least 5 signs:
@property (strong, nonatomic) NSString *password;
@end
@implementation UserAccount
- (NSError *)validate {
NSError *error = nil;
[NGRValidator validateModel:self error:&error delegate:nil rules:^NSArray *{
return @[NGRValidate(@"email").required().syntax(NGRSyntaxEmail),
NGRValidate(@"password").required().minLength(5)];
}];
return error;
}
@end
让我们再深入一步。考虑这个模型应被用于登录和密码修改。而且为了修改密码,用户需要提供旧密码、新密码和重复的新密码。显然,新密码和重复的新密码在登录时不应被验证。改进后的 UserAccount
模型如下所示
@interface UserAccount : NSObject
//should have email syntax:
@property (strong, nonatomic) NSString *email;
//should have at least 5 signs:
@property (strong, nonatomic) NSString *password;
//should have at least 5 signs and be different than password. Validated only on "changePassword" scenario.
@property (strong, nonatomic) NSString *newPassword;
//should have at least 5 signs and be same as newPassword. Validated only on "changePassword" scenario.
@property (strong, nonatomic) NSString *repeatedNewPassword;
@end
@implementation UserAccount
- (NSError *)validateWithScenario:(NSString *)scenario {
NSError *error = nil;
[NGRValidator validateModel:self error:&error scenario:scenario delegate:nil rules:^NSArray *{
return @[NGRValidate(@"email").required().syntax(NGRSyntaxEmail),
NGRValidate(@"password").required().minLength(5),
NGRValidate(@"newPassword").required().minLength(5).differ(self.password).onScenarios(@[@"changePassword"]),
NGRValidate(@"repeatedNewPassword").required().match(self.newPassword).onScenarios(@[@"changePassword"])];
}];
return error;
}
@end
这就完成了!所有验证需求都在一个地方。继续阅读以了解更多关于 规则、场景 和 消息 的信息。
gem install cocoapods
获取它!)在您的项目 git 文件夹中输入
git submodule init
git submodule add --copy link to the repo--
git submodule update
这非常不建议,因为您将无法看到代码更新。克隆或下载源代码,从 NGRValidator 文件夹中复制所有文件。
当您想要使用它时,请使用 #import "NGRValidator"
。
与其他许多库一样,NGRValidator 提供了方便的 VALIDATOR_SHORTHAND
,允许在某些方法中省略前缀。要使用它,请在 #import
之前使用它:
#define VALIDATOR_SHORTHAND
然后您可以用 validate(...)
代替 NGRValidate(...)
。
验证有三种通用方法:
+ (NSError *)validateValue:(NSObject *)value
named:(NSString *)name
rules:(void (^)(NGRPropertyValidator *validator))rules;
+ (BOOL)validateModel:(NSObject *)model
error:(NSError **)error
delegate:(id<NGRMessaging>)delegate
rules:(NSArray *(^)())rules;
// with scenario counterpart:
+ (BOOL)validateModel:(NSObject *)model
error:(NSError **)error
scenario:(NSString *)scenario
delegate:(id<NGRMessaging>)delegate
rules:(NSArray *(^)())rules;
+ (NSArray *)validateModel:(NSObject *)model
delegate:(id<NGRMessaging>)delegate
rules:(NSArray *(^)())rules;
// with scenario counterpart:
+ (NSArray *)validateModel:(NSObject *)model
scenario:(NSString *)scenario
delegate:(id<NGRMessaging>)delegate
rules:(NSArray *(^)())rules;
秘密!如果出现错误,您可以通过检查 error.userInfo[NGRValidatorPropertyNameKey]
确定哪个属性未验证通过。
NGRValidator 提供了许多可用的规则
required()
- 验证属性是否为 nil 或不为 nil。如果不要求必需且已附加其他验证规则(如 .decimal()
),则属性仅在非 nil 时进行验证。
allowEmpty()
- 验证属性是否可以为空(意味着其长度或计数等于 0)。默认情况下不能为空。如果允许为空,则验证器在属性为空时通过验证。适用于必需和非必需规则。**注意**:适用于 NSString
、NSAttributedString
、NSData
、NSArray
、NSSet
、NSDictionary
(以及它们的可变版本)。
order(NSUInteger)
- 改变 NGRPropertyValidator
的优先级。默认情况下,所有属性验证器具有相同的优先级,并且将按照在 rules:
块中返回的 NSArray
的顺序调用。
NSString:
minLength(NSUInteger)
- 验证 NSString 的最小长度(包含)。maxLength(NSUInteger)
- 验证 NSString 的最大长度(包含)。lengthRange(NSUInteger, NSUInteger)
- 验证 NSString 的最小和最大长度(包含)。exactLength(NSUInteger)
- 验证 NSString 的精确长度。match(NSString *)
- 验证 NSString 是否匹配另一个 NSString。differ(NSString *)
- 验证 NSString 是否与另一个 NSString 不相同。decimal()
- 验证 NSString 是否只包含十进制符号。语法:
syntax(NGRSyntax)
- 验证 NSString 是否具有给定的语法。可选的默认语法有 3 种NGRSyntaxEmail
- 验证电子邮件语法。NGRSyntaxName
- 验证字符串是否仅包含字母符号。NGRSyntaxHTTP
- 验证 HTTP URL 的语法。regex(NSString *, NSRegularExpressionOptions)
- 验证 NSString 是否匹配给定正则表达式模式(带有选项)。NSNumber:
min(float)
- 验证 NSNumber 的下限(包含)。max(float)
- 验证 NSNumber 的上限(包含)。range(float, float)
- 验证 NSNumber 的最小和最大值(包含)。exact(float)
- 验证 NSNumber 的确切值。beFalse()
- 验证 NSNumber 是否表示为假状态。beTrue()
- 验证 NSNumber 是否表示为真状态。NSDate:
earlierThan(NSDate *)
- 验证 NSDate 属性是否早于给定日期(包含)。earlierThanOrEqualTo(NSDate *)
- 验证 NSDate 属性是否早于或等于给定日期(包含)。laterThan(NSDate *)
- 验证 NSDate 属性是否晚于给定日期(包含)。laterThanOrEqualTo(NSDate *)
- 验证 NSDate 属性是否晚于或等于给定日期(包含)。betweenDates(NSDate *, NSDate *, BOOL)
- 验证 NSDate 属性是否在给定日期之间。布尔参数指定比较的包含性。NSArray:
includes(NSObject *)
- 验证给定的对象是否包含在要验证的数组属性中。excludes(NSObject *)
- 验证给定的对象是否排除在要验证的数组属性之外。includedIn(NSArray *)
- 验证要验证的属性是否包含在给定的数组中。如果数组为空,验证将返回错误。excludedFrom(NSArray *)
- 验证要验证的属性是否排除在给定的数组之外。如果数组为空,验证将通过。情景允许在所有可能的操作中保持相同的模型。有时某些属性对于某些操作可能是强制性的,而对于其他操作则是可选的。情景使得模型验证更加灵活、易于使用,而不需要任何条件语句。如果属性应符合指定的情景,则使用 NSArray
传入情景。
onScenarios(NSArray *)
不符合任何情景的属性将在每个情景中进行验证。请记住以 NSString
的形式传递情景名称。
虽然 NGRValidator 为每种验证都包含默认错误消息,但也可能自定义它们。有两种方法可以实现这一点:
rules
块中使用 msg
前缀方法NGRValidate(@"password").minLength(5).msgTooShort(@"should have at least 5 signs")
请注意,NGRValidator 将在错误描述中使用已验证属性的名称的首字母大写版本。不过,使用以下方法可以本地化其名称:
localizedName(NSString *)
NGRMessaging
代理并返回相应属性键的错误键-消息字典- (NSDictionary *)validationErrorMessagesByPropertyKey {
return @{@"password" :
@{MSGTooShort : @"Password should have at least 5 signs."}
};
}
这两种方法可以同时使用。消息的获取顺序如下:
- 如果验证器遇到任何错误,它将首先询问代理错误描述。
- 如果代理为 nil 或验证器找不到预期错误键和属性名称的消息,则将在规则块中查找错误描述。
- 如果开发人员没有为遇到的错误声明消息,验证器将使用库准备的默认消息。
有关更多信息,请参阅 消息系统。
NGRValidator 包含糖语法以增强可读性和向代码中引入自然语言。
is, are, on, has, have, to, toNot, notTo, be, with, should
注意糖语法和常规验证方法之间的区别
validation method has to be invoked always with parentheses (even if do not take any parameter).
v
validate(@"password").is.required()
^
sugar syntax is always invoked without parentheses.
包含 4 个示例
当您按 ⌘+R
时,将自动触发 UI 示例。要启用编码示例,请在 AppDelegate
中将 logStory
标志从 NO
更改为 YES
。为了提高 story
的可读性和理解性,在 story
方法的开头设置断点并逐行跟踪调试器。
NGRValidator 在 MIT 许可证 下提供。
首先,感谢您的贡献!以下是您需要遵循的一些指南:
变更日志在此 处 可用。
您可以随时通过 打开问题 来贡献、评论、提出问题以及分享您的想法。
您还可以阅读我们的博客文章 介绍:开源 NGRValidator。
由 Patryk Kaczmarek 创建和维护。
版权所有 © 2014 - 2015 Netguru