Validation, searching and filtering made easy for swift.

carthage, cocoapods, filtering, searching, swift, swift-4, swift4, validation, xcode, xcode9
pod try Quiver



license Swift 4.0 Xcode 9.0 CocoaPods Compatible Carthage compatible Build Status codecov codebeat badge

Quiver is a library that provides an easy way to validate, search and filter objects.



pod 'Quiver', '~> 1.0'


github "heitorgcosta/Quiver" ~> 1.0  



Objects can be easily validated by implementing the Validatable protocol. To do so, validations(with:) must be implemented. The mapping is made with the new Swift 4 smart keypaths.

struct Person {
    var name: String?
    var age: Int?

extension Person: Validatable {
    func validations(with mapper: ValidatorMapper) {
        // Name is required and must be at least 4 characters long.
        mapper[\Person.name] = [.required(),
                                .length(min: 4)]

        // Age is required and must be 18 or over
        mapper[\Person.age] = [.required(),
                               .greaterOrEqual(to: 18)]

Any object implementing Validatable can call validate(), which returns a result object.

let person = Person(name: "Hector", age: 23)
let result = person.validate()

print(result.success) // Prints 'true'

The results also contains the errors occurred.

let person = Person(name: "Hector", age: nil) 
let result = person.validate()

print(result.success) // Prints 'false'
print(result.error.items.count) // Prints 1, since it does not fulfill the 'required' validation

Also, each validator can contain a custom message defined by you.

extension Person: Validatable {
    func validations(with mapper: ValidatorMapper) {
        mapper[\Person.name] = [.required(message: "The name is required"),
                                .length(min: 4, message: "The name should be at least 4 characters long")]

        mapper[\Person.age] = [.required(message: "The age is required"),
                               .greaterOrEqual(to: 18, message: "The age should be 18 or over")]

let person = Person(name: "Heitor", age: 17)
let result = person.validate()

print(result.error.firstItem?.message ?? "No errors found") // Will print 'The age should be 18 or over'

Validators are still in the beginning and more will be added in the future.


First, objects to be searched must implement the Searchable protocol. The searchableFields() function should return all searchable properties.

struct Person {
    var name: String
    var age: Int

extension Person: Searchable {
    func searchableFields() -> [Any?] {
        return [name, age]

Then, any array of this object can use the search() function to get an array with the matching results.

// If any searchable field of a person contains "John", it is returned in the result array.

let results = personsArray.search(with: "John") // Search is not case sensitive by default.
let caseSensitiveResults = personsArray.search(with: "John", caseSensitive: true) // Explicit case sensitivity


An array of objects can be filtered using the validators included in this library using the filter(by:with:), using a keypath and an array of validators.

let persons: [Person] = [] // Just imagine a great collection of persons
let filtered = persons.filter(by: \Person.name, with: [.length(min: 4)]) // Filter persons that contains name with length of at least 4 characters


Quiver is released under the MIT License.