Validator 3.2.1

Validator 3.2.1

Tests已测试
Lang语言 SwiftSwift
许可证 MIT
Released最新版本2019年6月
SPM支持 SPM

Adam Waite 维护。



Validator 3.2.1

Validator

Validator 是一个用 Swift 编写的用户输入验证库。它全面、可扩展,用户界面由您来决定。

以下是如何验证电子邮件地址的示例:

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)

.. 或验证一个文本字段是否包含有效的维萨或美国运通卡号

let cardRule = ValidationRulePaymentCard(availableTypes: [.visa, .amex], error: validationError)
paymentCardTextField.validate(cardRule) // -> .valid or .invalid(validationError) depending on what's in paymentCardTextField

功能

  • 验证规则
    • 必填
    • 相等性
    • 比较
    • 长度(最小、最大、范围)
    • 模式(电子邮件、密码约束等...)
    • 包含
    • URL
    • 支付卡(Luhn 验证,接受类型)
    • 条件(快速编写您自己的)
  • 使用单个 API 扩展 Swift 标准库类型(不仅仅是字符串!)
  • UIKit 元素扩展
  • 开放的验证错误类型
  • 基于开放协议的实现
  • 全面的测试覆盖率
  • 全面的代码文档

示例

demo-vid

安装

CocoaPods

CocoaPods Compatible CocoaPods Compatible

pod 'Validator'

Carthage

Carthage Compatible

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 提供了一些通用的模式在模式目录中。

let emailRule = ValidationRulePattern(pattern: EmailValidationPattern.standard, error: validationError)

let digitRule = ValidationRulePattern(pattern: ContainsNumberValidationPattern(), error: someValidationErrorType)

let helloRule = ValidationRulePattern(pattern: ".*hello.*", error: validationError)

包含

验证一个 Equatable 类型是否在预定义的 SequenceType 元素(其中 SequenceTypeElement 与输入类型匹配)内。

let stringContainsRule = ValidationRuleContains<String, [String]>(sequence: ["hello", "hi", "hey"], error: validationError)

let rule = ValidationRuleContains<Int, [Int]>(sequence: [1, 2, 3], error: validationError)

URL

验证一个 String 是否是一个符合 RFC 2396 的有效 URL。

let urlRule = ValidationRuleURL(error: validationError)

支付卡

通过首先运行通过Luhn检查算法,然后确保它符合众多支付卡提供商的格式来验证一个String是否为有效的支付卡号码。

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

示例

struct HappyRule {
    typealias InputType = String
    var error: ValidationError
    func validate(input: String) -> Bool {
        return input == "😀"
    }
}

如果你的自定义规则已经存在于库中,并且你认为它可能对其他人有用,那么通过在pull请求中添加它将非常有益。

多个验证规则(ValidationRuleSet

可以组合验证规则到包含一组验证类型的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

任何符合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 协议以使新类型可验证。

扩展 Thing : Validatable {}

注意:协议扩展内部的实现应该意味着除非您需要验证多个属性,否则您不需要自己实现任何东西。

ValidationResult

validate: 方法返回一个 ValidationResult 枚举。 ValidationResult 可以为两种形式之一

  1. .valid:输入满足验证规则。
  2. .invalid:输入不满足验证规则。一个 .invalid 结果有一个与 ValidationError 兼容的关联数组。

Errors

使用任何 ValidationError 来初始化规则,当验证失败时与此结果一起传递。

示例

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

验证 UIKit 元素

符合 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 个步骤中配置为在输入更改时自动验证。

  1. 附加一组默认规则

    let textField = UITextField()
    var rules = ValidationRuleSet<String>()
    rules.add(rule: someRule)
    textField.validationRules = rules
  2. 附加一个闭包以在输入更改时触发

    textField.validationHandler = { result in
      switch result {
      case .valid:
    	    print("valid!")
      case .invalid(let failureErrors):
    	    let messages = failureErrors.map { $0.message }
        print("invalid!", messages)
      }
    }
  3. 开始观察

    textField.validateOnInputChange(enabled: true)

注意 - 使用 .validateOnInputChange(enabled: false) 来停止观察。

将UI元素扩展为可验证的

ValidatableInterfaceElement 协议扩展,使界面元素可验证。

示例

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()
    }

}

协议扩展内部实现应意味着您只需实现以下内容:

  1. typealias:要验证的输入类型(例如 UITextFieldString)。
  2. inputValue:要验证的输入值(例如 UITextFieldtext 值)。
  3. validateOnInputChange: 方法:配置输入变更观察。

示例

本存储库中有一个示例项目。

贡献

非常欢迎任何贡献和建议!请确保任何新的代码都有单元测试,并且所有现有的测试都通过。请更新README包括任何新功能。谢谢!

联系方式

@adamwaite

许可

特此授予任何人,免费获得此软件及其相关文档文件(以下称为“软件”)的副本(“软件”),无限制地处理软件,包括但不限于使用、复制、修改、合并、发布、分发、再许可和/或销售软件副本的权利,并允许提供软件的人进行此类操作,但受以下条件约束:

上述版权声明和本许可声明应包含在软件的所有副本或主要部分中。

本软件按“原样”提供,不提供任何明示或暗示的保证,包括但不限于适销性、适用于特定目的和非侵权的保证。在任何情况下,作者或版权持有人不对任何索赔、损害或其他责任负责,无论基于合同行为、侵权行为或其他行为,无论是源自、由或与软件、软件的使用或其他与软件相关的行为有关。