SwiftCop is a validation library fully written in Swift and inspired by the clarity of Ruby On Rails Active Record validations.

Overview

SwiftCop

SwiftCop is a validation library fully written in Swift and inspired by the clarity of Ruby On Rails Active Record validations.

Build Status codecov.io codecov.io

Objective

Build a standard drop-in library for validations in Swift while making it easily extensible for users to create custom validations. And avoid developers from writing over and over again the same code and validations for different projects.

Features

  • Quick validations.
  • Super simple and declarative syntax.
  • Easily extensible.
  • Fully Swift 4.0

Modules

SwiftCop was built around three different concepts:

Trial

Trial is an Enum that implements the TrialProtocol

public protocol TrialProtocol {
	func trial() -> ((_ evidence: String) -> Bool)
}

We can use Trial to quickly validate strings. SwiftCop ships with a very fully featured Trial implementation. The following trials are provided:

Exclusion([String])

This validates that the attributes are not included in the evidence string.

let exclusionTrial = Trial.exclusion([".com",".ar", ".uy"])
let trial = exclusionTrial.trial()

XCTAssertFalse(trial("http://www.nytimes.com"))
XCTAssertFalse(trial("http://www.lanacion.com.ar"))
XCTAssertTrue(trial("http://www.elpais.es"))

Format(String)

This validates whether the evidence matches a given regular expression.

let formatTrial = Trial.format("^#([a-f0-9]{6}|[a-f0-9]{3})$") // hexa number with #
let trial = formatTrial.trial()

XCTAssertTrue(trial("#57b5b5"))
XCTAssertFalse(trial("57b5b5"))
XCTAssertFalse(trial("#h7b5b5"))

Inclusion([String])

This validates that the attributes are included in the evidence string.

let inclusionTrial = Trial.inclusion([".com",".ar", ".uy"])
let trial = inclusionTrial.trial()

XCTAssertTrue(trial("http://www.nytimes.com"))
XCTAssertTrue(trial("http://www.lanacion.com.ar"))
XCTAssertFalse(trial("http://www.elpais.es"))

Email

This validates whether the evidence is an email or not.

let emailTrial = Trial.email
let trial = emailTrial.trial()
XCTAssertTrue(trial("[email protected]"))

Length(Length,Any)

This validates the length of given evidence:

let lengthTrial = Trial.Length(.Is, 10)
let trial = lengthTrial.trial()
XCTAssertTrue(trial("0123456789"))
let lengthTrial = Trial.Length(.Minimum, 10)
let trial = lengthTrial.trial()
XCTAssertTrue(trial("0123456789"))
let lengthTrial = Trial.Length(.Maximum, 10)
let trial = lengthTrial.trial()		
XCTAssertTrue(trial("0123456789"))
let interval = Trial.Length(.In, 2..<5 as HalfOpenInterval)
let trial = interval.trial()
XCTAssertTrue(trial("1234"))
let interval = Trial.Length(.In, 2...5 as ClosedInterval)
let trial = interval.trial()
XCTAssertFalse(trial("123456"))

Suspect

The Suspect is a Struct that is the glue between some other concepts always used while validating fields. It puts together a UITextField that is going to be the source of the evidence, a sentence that is going to be the text shown if the suspect is guilty (when the Trial returns false) and the Trial itself, that can be a custom made trial for the suspect or you can use one of the trials provided by the library:

Suspect(view: UITextField, sentence: String, trial: TrialProtocol)
Suspect(view: UITextField, sentence: String, trial: (String) -> Bool)

We can check if the Suspect is guilty or not with:

func isGuilty() -> Bool

This method is going to return true if the Trial returns false.

Also we can directly ask for the verdict on the Suspect, this is going to check if it's guilty or not and then return and empty string ("") or the sentence.

For example:

let suspect = Suspect(view: self.dummyTextField, sentence: "Invalid email", trial: .Email)		
let verdict = suspect.verdict() // this can be "" or "Invalid Email"

SwiftCop

Finally we have the guy that is going to enforce the validations! The cop is going to get all the suspects together and give us the tools to check who are the guilty suspects or if there is any guilty suspect at all.

As you can imagine this is going to add a suspect under the vigilance of a cop, we can add as many suspects as we want:

open func addSuspect(_ suspect: Suspect)

This will let us check if there is any guilty suspect between all the suspects under the surveillance of our cop:

public func anyGuilty() -> Bool

This will let us know all the guilty suspects our cop found:

public func allGuilties() -> Array<Suspect>

This will let us check if a UITextField that is suspect is guilty or not:

public func isGuilty(textField: UITextField) -> Suspect?

Example

The example is shipped in the repository:

class ViewController: UIViewController {
	@IBOutlet weak var validationLabel: UILabel!

	@IBOutlet weak var fullNameMessage: UILabel!
	@IBOutlet weak var emailMessage: UILabel!
	@IBOutlet weak var passwordMessage: UILabel!

	@IBOutlet weak var fullName: UITextField!
	@IBOutlet weak var emailTextField: UITextField!
	@IBOutlet weak var password: UITextField!

	let swiftCop = SwiftCop()

	override func viewDidLoad() {
		super.viewDidLoad()

		swiftCop.addSuspect(Suspect(view: self.fullName, sentence: "More Than Two Words Needed"){
			return $0.components(separatedBy: " ").filter{$0 != ""}.count >= 2
		})
		swiftCop.addSuspect(Suspect(view:self.emailTextField, sentence: "Invalid email", trial: Trial.email))
		swiftCop.addSuspect(Suspect(view:self.password, sentence: "Minimum 4 Characters", trial: Trial.length(.minimum, 4)))
	}

	@IBAction func validateFullName(_ sender: UITextField) {
		self.fullNameMessage.text = swiftCop.isGuilty(sender)?.verdict()
	}

	@IBAction func validateEmail(_ sender: UITextField) {
		self.emailMessage.text = swiftCop.isGuilty(sender)?.verdict()
	}

	@IBAction func validatePassword(_ sender: UITextField) {
		self.passwordMessage.text = swiftCop.isGuilty(sender)?.verdict()
	}

	@IBAction func allValid(_ sender: UITextField) {
		let nonGultiesMessage = "Everything fine!"
		let allGuiltiesMessage = swiftCop.allGuilties().map{ return $0.sentence}.joined(separator: "\n")

		self.validationLabel.text = allGuiltiesMessage.characters.count > 0 ? allGuiltiesMessage : nonGultiesMessage
	}

	@IBAction func hideKeyboard(_ sender: AnyObject) {
		self.view.endEditing(true)
	}
}

SwiftCopExampel

Installation

You can just clone the repo and copy the SwiftCop folder to your project or you can use one of the following options:

Setting up with CocoaPods

pod 'SwiftCop'

Then:

import SwiftCop

And you are all set!

Setting up with Carthage

  • TODO
You might also like...
Cross-platform static analyzer and linter for Swift.
Cross-platform static analyzer and linter for Swift.

Wiki • Installation • Usage • Features • Developers • License Tailor is a cross-platform static analysis and lint tool for source code written in Appl

Type-safe observable values and collections in Swift

GlueKit ⚠️ WARNING ⚠️ This project is in a prerelease state. There is active work going on that will result in API changes that can/will break code wh

Makes it easier to support older versions of iOS by fixing things and adding missing methods

PSTModernizer PSTModernizer carefully applies patches to UIKit and related Apple frameworks to fix known radars with the least impact. The current set

Find common xib and storyboard-related problems without running your app or writing unit tests.
Find common xib and storyboard-related problems without running your app or writing unit tests.

IBAnalyzer Find common xib and storyboard-related problems without running your app or writing unit tests. Usage Pass a path to your project to ibanal

Skredvarsel app - an iOS, iPadOS, and macOS application that provides daily avalanche warnings from the Norwegian Avalanche Warning Service API
Skredvarsel app - an iOS, iPadOS, and macOS application that provides daily avalanche warnings from the Norwegian Avalanche Warning Service API

Skredvarsel (Avalanche warning) app is an iOS, iPadOS, and macOS application that provides daily avalanche warnings from the Norwegian Avalanche Warning Service API

Simple iOS app blackbox assessment tool. Powered by frida.re and vuejs.
Simple iOS app blackbox assessment tool. Powered by frida.re and vuejs.

Discontinued Project This project has been discontinued. Please use the new Grapefruit #74 frida@14 compatibility issues frida@14 introduces lots of b

Exclude files and folders from Alfred’s search results
Exclude files and folders from Alfred’s search results

Ignore in Alfred Alfred Workflow Exclude files and folders from Alfred’s search results ⤓ Download Workflow About The macOS metadata search API only a

Lint anything by combining the power of Swift & regular expressions.
Lint anything by combining the power of Swift & regular expressions.

Installation • Getting Started • Configuration • Xcode Build Script • Donation • Issues • Regex Cheat Sheet • License AnyLint Lint any project in any

An Xcode formatter plug-in to format your swift code.
An Xcode formatter plug-in to format your swift code.

Swimat Swimat is an Xcode plug-in to format your Swift code. Preview Installation There are three way to install. Install via homebrew-cask # Homebrew

Releases(0.0.1)
Owner
Andres Canal
Andres Canal
Trackable is a simple analytics integration helper library. It’s especially designed for easy and comfortable integration with existing projects.

Trackable Trackable is a simple analytics integration helper library. It’s especially designed for easy and comfortable integration with existing proj

Vojta Stavik 145 Apr 14, 2022
iOS library to help detecting retain cycles in runtime.

FBRetainCycleDetector An iOS library that finds retain cycles using runtime analysis. About Retain cycles are one of the most common ways of creating

Facebook 4.1k Dec 26, 2022
Aardvark is a library that makes it dead simple to create actionable bug reports.

Aardvark Aardvark makes it dead simple to create actionable bug reports. Aardvark is made up of a collection of frameworks that provide different bug

Square 257 Dec 19, 2022
A dynamic library for Cornerstone macOS.

Cornerstone-Hook A dynamic library for Cornerstone macOS. Screenshot Overview Quick Start sudo ./install.sh Install or Upgrade CornerstoneStart.app su

ivar 3 Oct 8, 2022
A library that enables dynamically rebinding symbols in Mach-O binaries running on iOS.

fishhook fishhook is a very simple library that enables dynamically rebinding symbols in Mach-O binaries running on iOS in the simulator and on device

Meta 4.9k Jan 8, 2023
Measure Swift code metrics and get reports in Xcode, Jenkins and other CI platforms.

Taylor ⚠️ Taylor is DEPRECATED. Use SwiftLint instead. A tool aimed to increase Swift code quality, by checking for conformance to code metrics. Taylo

YOPESO 301 Dec 24, 2022
A static source code analysis tool to improve quality and reduce defects for C, C++ and Objective-C

OCLint - https://oclint.org OCLint is a static code analysis tool for improving quality and reducing defects by inspecting C, C++ and Objective-C code

The OCLint Static Code Analysis Tool 3.6k Dec 29, 2022
A tool for Swift code modification intermediating between code generation and formatting.

swift-mod A tool for Swift code modification intermediating between code generation and formatting. Overview swift-mod is a tool for Swift code modifi

Ryo Aoyama 95 Nov 3, 2022
A command-line tool and Xcode Extension for formatting Swift code

Table of Contents What? Why? How? Command-line tool Xcode source editor extension Xcode build phase Via Applescript VSCode plugin Sublime Text plugin

Nick Lockwood 6.3k Jan 8, 2023
A tool to enforce Swift style and conventions.

SwiftLint A tool to enforce Swift style and conventions, loosely based on the now archived GitHub Swift Style Guide. SwiftLint enforces the style guid

Realm 16.9k Jan 9, 2023