Validator 是一个用 Swift 编写的用户输入验证库。它功能全面,设计可扩展,并且将 UI 的选择权留给你。
以下是如何验证电子邮件地址的示例
let emailRule = ValidationRulePattern(pattern: EmailValidationPattern.standard, error: validationError)
"invalid@email,com".validate(emailRule) // -> .invalid(validationError)
... 或者验证用户是否超过 18 岁
let eighteenYearsAgo = Date().addingTimeInterval(-568024668)
let drinkingAgeRule = ValidationRuleComparison<Date>(min: eighteenYearsAgo, error: validationError)
let dateOfBirth = Date().addingTimeInterval(-662695446) // 21 years old
dateOfBirth.validate(rule: rule) // -> .valid
... 或者验证数字是否在指定范围内
let numericRule = ValidationRuleComparison<Int>(min: 50, max: 100, error: validationError)
42.validate(numericRule) // -> .invalid(validationError)
... 或者验证文本字段是否包含有效的 Visa 或 American Express 卡号
let cardRule = ValidationRulePaymentCard(availableTypes: [.visa, .amex], error: validationError)
paymentCardTextField.validate(cardRule) // -> .valid or .invalid(validationError) depending on what's in paymentCardTextField
pod 'Validator'
github "adamwaite/Validator"
Validator
可以使用一个或多个 ValidationRule
来验证任何 Validatable
类型。 验证操作返回一个 ValidationResult
,它匹配 .valid
或 .invalid([Error])
。
let rule = ValidationRulePattern(pattern: EmailValidationPattern.standard, error: validationError)
let result = "invalid@email,com".validate(rule: rule)
// Note: the above is equivalent to Validator.validate(input: "invalid@email,com", rule: rule)
switch result {
case .valid: print("😀")
case .invalid(let failures): print(failures.first?.message)
}
验证类型是否存在(非 nil)。
let stringRequiredRule = ValidationRuleRequired<String?>(error: validationError)
let floatRequiredRule = ValidationRuleRequired<Float?>(error: validationError)
注意 - 您不能在可选的 Validatable
类型上使用 validate
(例如,myString?.validate(aRule...)
),因为可选链机制将绕过调用。 "thing".validate(rule: aRule...)
是可以的。 要以此方式验证可选类型的 required 属性,请使用:Validator.validate(input: anOptional, rule: aRule)
。
验证 Equatable
类型是否等于另一个类型。
let staticEqualityRule = ValidationRuleEquality<String>(target: "hello", error: validationError)
let dynamicEqualityRule = ValidationRuleEquality<String>(dynamicTarget: { return textField.text ?? "" }, error: validationError)
根据最大值和最小值验证 Comparable
类型。
let comparisonRule = ValidationRuleComparison<Float>(min: 5, max: 7, error: validationError)
验证 String
长度是否满足最小值,最大值或范围。
let minLengthRule = ValidationRuleLength(min: 5, error: validationError)
let maxLengthRule = ValidationRuleLength(max: 5, error: validationError)
let rangeLengthRule = ValidationRuleLength(min: 5, max: 10, error: validationError)
根据模式验证 String
。
ValidationRulePattern
可以使用 String
模式或符合 ValidationPattern
的类型进行初始化。 Validator 在 Patterns 目录中提供了一些常用模式。
let emailRule = ValidationRulePattern(pattern: EmailValidationPattern.standard, error: validationError)
let digitRule = ValidationRulePattern(pattern: ContainsNumberValidationPattern(), error: someValidationErrorType)
let helloRule = ValidationRulePattern(pattern: ".*hello.*", error: validationError)
验证 Equatable
类型是否在预定义的 SequenceType
的元素中(其中 SequenceType
的 Element
匹配输入类型)。
let stringContainsRule = ValidationRuleContains<String, [String]>(sequence: ["hello", "hi", "hey"], error: validationError)
let rule = ValidationRuleContains<Int, [Int]>(sequence: [1, 2, 3], error: validationError)
验证 String
以查看它是否是符合 RFC 2396 的有效 URL。
let urlRule = ValidationRuleURL(error: validationError)
验证 String
以查看它是否是有效的支付卡号,首先通过 Luhn 校验算法 进行验证,然后确保它遵循多个支付卡提供商的格式。
public enum PaymentCardType: Int {
case amex, mastercard, visa, maestro, dinersClub, jcb, discover, unionPay
///...
要针对任何卡类型进行验证(仅 Luhn 校验)
let anyCardRule = ValidationRulePaymentCard(error: validationError)
要针对一组接受的卡类型进行验证(例如,本示例中的 Visa,Mastercard 和 American Express)
let acceptedCardsRule = ValidationRulePaymentCard(acceptedTypes: [.visa, .mastercard, .amex], error: validationError)
使用自定义条件验证 Validatable
类型。
let conditionRule = ValidationRuleCondition<[String]>(error: validationError) { $0.contains("Hello") }
通过遵循 ValidationRule
协议来创建你自己的验证规则
protocol ValidationRule {
typealias InputType
func validate(input: InputType) -> Bool
var error: ValidationError { get }
}
示例 (Example)
struct HappyRule {
typealias InputType = String
var error: ValidationError
func validate(input: String) -> Bool {
return input == "😀"
}
}
如果你的自定义规则在库中尚不存在,并且你认为它对其他人可能有用,那么如果你通过 pull request 将其添加进来,那就太好了。
验证规则可以组合成一个 ValidationRuleSet
,其中包含验证类型的规则集合。
var passwordRules = ValidationRuleSet<String>()
let minLengthRule = ValidationRuleLength(min: 5, error: validationError)
passwordRules.add(rule: minLengthRule)
let digitRule = ValidationRulePattern(pattern: .ContainsDigit, error: validationError)
passwordRules.add(rule: digitRule)
任何符合 Validatable
协议的类型都可以使用 validate:
方法进行验证。
// Validate with a single rule:
let result = "some string".validate(rule: aRule)
// Validate with a collection of rules:
let result = 42.validate(rules: aRuleSet)
扩展 Validatable
协议以使新类型可验证。
extension Thing : Validatable { }
注意:协议扩展中的实现应该意味着你不需要自己实现任何东西,除非你需要验证多个属性。
validate:
方法返回 ValidationResult
枚举。 ValidationResult
可以采用以下两种形式之一
.valid
:输入满足验证规则。.invalid
:输入未能通过验证规则。 .invalid
结果具有符合 ValidationError
的类型的关联数组。使用任何 ValidationError
初始化规则,以便在验证失败时传递结果。
示例 (Example)
struct User: Validatable {
let email: String
enum ValidationErrors: String, ValidationError {
case emailInvalid = "Email address is invalid"
var message { return self.rawValue }
}
func validate() -> ValidationResult {
let rule ValidationRulePattern(pattern: .emailAddress, error: ValidationErrors.emailInvalid)
return email.validate(rule: rule)
}
}
符合 ValidatableInterfaceElement
的 UIKit 元素可以使用 validate:
方法验证其输入。
let textField = UITextField()
textField.text = "I'm going to be validated"
let slider = UISlider()
slider.value = 0.3
// Validate with a single rule:
let result = textField.validate(rule: aRule)
// Validate with a collection of rules:
let result = slider.validate(rules: aRuleSet)
可以配置 ValidatableInterfaceElement
在输入更改时自动验证,分 3 步。
附加一组默认规则
let textField = UITextField()
var rules = ValidationRuleSet<String>()
rules.add(rule: someRule)
textField.validationRules = rules
附加一个闭包以在输入更改时触发
textField.validationHandler = { result in
switch result {
case .valid:
print("valid!")
case .invalid(let failureErrors):
let messages = failureErrors.map { $0.message }
print("invalid!", messages)
}
}
开始观察
textField.validateOnInputChange(enabled: true)
注意 - 使用 .validateOnInputChange(enabled: false)
结束观察。
扩展 ValidatableInterfaceElement
协议以使接口元素可验证。
示例 (Example)
extension UITextField: ValidatableInterfaceElement {
typealias InputType = String
var inputValue: String { return text ?? "" }
func validateOnInputChange(enabled: Bool) {
switch validationEnabled {
case true: addTarget(self, action: #selector(validateInputChange), forControlEvents: .editingChanged)
case false: removeTarget(self, action: #selector(validateInputChange), forControlEvents: .editingChanged)
}
}
@objc private func validateInputChange(_ sender: UITextField) {
sender.validate()
}
}
协议扩展中的实现应该意味着你只需要实现
typealias
:要验证的输入类型(例如 UITextField
的 String
)。inputValue
:要验证的输入值(例如 UITextField
的 text
值)。validateOnInputChange:
方法:配置输入更改观察。此存储库中有一个示例项目。
非常欢迎任何贡献和建议! 请确保任何新代码都包含单元测试,并且所有现有测试都通过。 请使用任何新功能更新 README。 谢谢!
特此授予任何人免费获得本软件及相关文档文件(“软件”)的副本的许可,以不受限制地处理本软件,包括但不限于使用、复制、修改、合并、发布、分发、再许可和/或销售软件副本的权利,并允许向其提供软件的人员这样做,但须符合以下条件
上述版权声明和本许可声明应包含在所有副本或本软件的主要部分中。
本软件按“原样”提供,不提供任何形式的明示或暗示的保证,包括但不限于适销性、特定用途适用性和非侵权性的保证。 在任何情况下,作者或版权所有者均不对任何索赔、损害或其他责任承担责任,无论是在合同诉讼、侵权诉讼或其他诉讼中,因软件或软件的使用或其他交易而引起或与之相关的任何索赔、损害或其他责任承担责任。