Swiftpack.co - amoriarty/ValidationsKit as Swift Package

Swiftpack.co is a collection of thousands of indexed Swift packages. Search packages.
See all packages published by amoriarty.
amoriarty/ValidationsKit 1.3.0
Model validation for iOS, inspired by Vapor/Validation
⭐️ 3
🕓 4 years ago
.package(url: "https://github.com/amoriarty/ValidationsKit.git", from: "1.3.0")

ValidationsKit

The purpose of this kit is to bring vapor/validation package to iOS, by removing Vapor core dependencies from it.

Example

Will try to add validations to a User model, in order to be conform for a registration process for example.
We first have to describe it as we usually do. We also make it conform to Codable and Refletable so it can naturally get path from the object

struct User {
    let mail: String
    let phone: String
    let password: String
    let website: String?
    let twitter: String?
}

extension User: Codable {}
extension User: Reflectable {}

Then we have to make this model conform to Validatable protocol by adding the validations() function. This return a Validations object for our model and allow us to add Validators to it.
Like the Vapor package, there's already some Validators you can use (such as mail, count, empty ...) or you can define you own validation rule through a closure:

extension User: Validatable {

    static func validations() throws -> Validations<User> {
        var validations = Validations(User.self)

        // 'mail' should be a valid mail address.
        validations.add(\.mail, .mail)

        // 'phone' should be a valid phone number.
        validations.add(\.phone, .phone) 

        // 'password' should have more than 8 characters.
        validations.add(\.password, .count(8...))

        // 'website' should be nil or be a valid url.
        validations.add(\.website, .nil || .url)

        // 'twitter' should be nil or began by '@'.
        validations.add(\.twitter, validator: { twitter in
        	guard let twitter = twitter else { return }
            guard twitter.first != "@" else { return }
            throw BasicValidationError("isn't a valid Twitter username")
        })
        
        return validations
    }

}

We now have a model setup and we can now call the validate() method on it.

let valid = User(mail: "[email protected]", phone: "++3642424242", password: "somepassword", website: nil, twitter: nil)
do { try valid.validate() }
catch {
	// Will never be executed because our model is valid.
}

let invalidWebsite = User(mail: "[email protected]", phone: "++3642424242", password: "somepassword", website: "notValidUrl", twitter: nil)
do { try invalidWebsite.validate() }
catch {
	print("\(error)") // 'website' isn't nil or isn't a valid url.
}

Or you can validate only specified fields:

try valid.validate(at: \User.mail, \User.password)

Finally, you can now define your own message to be thrown in a case of validations failure, which can be handy to pass some localised string or just display some custom message to end user:

struct User: Validatable {
    let age: Int
    
    static func validations() throws -> Validations<User> {
        var validations = Validations(User.self)
        
        validations.add(\.age, .range(..< 12)) { age in
            "You have to be at most 12 for doing this, \(age) is too old for that stuff..."
        }
        
        return validations
    }

}

do {
    try User(age: 42)
} catch {
    print("\(error)") // "You have to be at most 12 for doing this, 42 is too old for that stuff..."
}

You can also take a look to a demo application in the ValidationsKitDemo directory.

Installation

Swift Package Manager

Add the GitHub link in you Package.swift as a dependencies:

.package(url: "https://github.com/amoriarty/ValidationsKit", from: "1.3.0"),

Add the dependency to your target:

.target(name: "your_target_name", dependencies: ["ValidationsKit"]),

Then update you project with:

$ swift package update

Cocoapods

Simply add this line in you pods dependencies:

pod 'ValidationsKit', '~> 1.3.0'

Thanks

I allow myself to thank very much Vapor community for all there works and great packages, which was really a model that I wanted to bring into iOS.

GitHub

link
Stars: 3
Last commit: 4 years ago
Advertisement: IndiePitcher.com - Cold Email Software for Startups

Release Notes

1.3.0
4 years ago

This release release include the following PR: #13

Custom validations with model

User can now define custom validations by taking the entire object as parameter instead of the field tested itself. This allow to access other attributes from the object when validating a single field:

struct User: Decodable, Reflectable {
    // A custom date formatter to validate the user birthday
    let formatter = DateFormatter()

    // Field set by the end user
    let birthday: String
}

extension User: Validatable {

    static func validations() throws -> Validations<User> {
        var validations = Validations(User.self)

        // We now can define a validation on the entire user, 
        // allowing us to access other field (here formatter)
        try validations.add(\.message, withModel: { user in
            guard user.formatter.date(from: user.birthday) == nil else { return }
            throw BasicValidationError("is not a valid date.")
        })

        return validations
    }

}

Swiftpack is being maintained by Petr Pavlik | @ptrpavlik | @swiftpackco | API | Analytics