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...)
可以正常工作。 要以这种方式验证可选类型是否必需,请使用: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。 谢谢!
特此授予任何人免费获得本软件及相关文档文件(“软件”)副本的许可,以不受限制地处理本软件,包括但不限于使用、复制、修改、合并、发布、分发、再许可和/或销售本软件的副本,并允许向其提供本软件的人员这样做,但须符合以下条件
以上版权声明和本许可声明应包含在所有副本或本软件的实质性部分中。
本软件按“原样”提供,不提供任何形式的明示或暗示保证,包括但不限于适销性、特定用途适用性和非侵权性的保证。 在任何情况下,作者或版权所有者均不对任何索赔、损害或其他责任负责,无论是在合同诉讼、侵权诉讼还是其他诉讼中,因本软件或本软件的使用或其他处理而产生或与之相关的责任。