Compare commits
14 Commits
master
...
remote-val
| Author | SHA1 | Date |
|---|---|---|
|
|
b9b9a65b74 | |
|
|
7bc7067515 | |
|
|
87a47a3107 | |
|
|
f9fad02c3d | |
|
|
0bd79451d2 | |
|
|
0d2b50c9a6 | |
|
|
d4aa8e594f | |
|
|
d359bf0683 | |
|
|
b57e924b26 | |
|
|
7c6bf284c4 | |
|
|
3f5fb305c3 | |
|
|
3a7d4956b9 | |
|
|
cb94d71119 | |
|
|
3bab916c05 |
30
README.md
30
README.md
|
|
@ -1,6 +1,5 @@
|
||||||
SwiftValidator
|
SwiftValidator
|
||||||
===============
|
=======
|
||||||
|
|
||||||
[](https://travis-ci.org/jpotts18/SwiftValidator) [](https://github.com/Carthage/Carthage) [](https://codecov.io/github/jpotts18/SwiftValidator?branch=master)
|
[](https://travis-ci.org/jpotts18/SwiftValidator) [](https://github.com/Carthage/Carthage) [](https://codecov.io/github/jpotts18/SwiftValidator?branch=master)
|
||||||
|
|
||||||
Swift Validator is a rule-based validation library for Swift.
|
Swift Validator is a rule-based validation library for Swift.
|
||||||
|
|
@ -146,6 +145,33 @@ class SSNVRule: RegexRule {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Remote Validation
|
||||||
|
|
||||||
|
Register field to `validator` with `remoteInfo` parameter set
|
||||||
|
|
||||||
|
`validator.registerField(emailTextField, errorLabel: emailErrorLabel, rules: [RequiredRule(), EmailRule()], remoteInfo: (urlString: "http://localhost:8000/emails/", error: "Email already in use"))`
|
||||||
|
|
||||||
|
Implement `ValidationDelegate`'s `remoteValidationRequest` method
|
||||||
|
```swift
|
||||||
|
func remoteValidationRequest(text: String, urlString: String, completion: (result: Bool) -> Void) {
|
||||||
|
// Add email to urlString
|
||||||
|
let newUrlString = "\(urlString)?email=\(text)"
|
||||||
|
YourNetworkingLibrary.request(.GET, newUrlString) { data -> Void in
|
||||||
|
|
||||||
|
if data.httpResponse.statusCode == 404 {
|
||||||
|
// resource was not found, therefore the text (username, email, etc) is available
|
||||||
|
completion(result: true)
|
||||||
|
}
|
||||||
|
|
||||||
|
if data.httpResponse.statusCode == 200 {
|
||||||
|
// resource was found, therefore the text (username, email, etc) is unavailable
|
||||||
|
completion(result: false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// end of remoteValidationRequest method
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
Credits
|
Credits
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
Pod::Spec.new do |s|
|
Pod::Spec.new do |s|
|
||||||
s.name = "SwiftValidator"
|
s.name = "SwiftValidator"
|
||||||
s.version = "3.0.1"
|
s.version = "3.0.4"
|
||||||
s.summary = "A UITextField Validation library for Swift"
|
s.summary = "A UITextField Validation library for Swift"
|
||||||
s.homepage = "https://github.com/jpotts18/SwiftValidator"
|
s.homepage = "https://github.com/jpotts18/SwiftValidator"
|
||||||
s.screenshots = "https://raw.githubusercontent.com/jpotts18/SwiftValidator/master/swift-validator-v2.gif"
|
s.screenshots = "https://raw.githubusercontent.com/jpotts18/SwiftValidator/master/swift-validator-v2.gif"
|
||||||
|
|
@ -9,7 +9,7 @@ Pod::Spec.new do |s|
|
||||||
s.social_media_url = "http://twitter.com/jpotts18"
|
s.social_media_url = "http://twitter.com/jpotts18"
|
||||||
s.platform = :ios
|
s.platform = :ios
|
||||||
s.ios.deployment_target = '8.0'
|
s.ios.deployment_target = '8.0'
|
||||||
s.source = { :git => "https://github.com/jpotts18/SwiftValidator.git", :tag => "3.0.1" }
|
s.source = { :git => "https://github.com/jpotts18/SwiftValidator.git", :tag => "3.0.4" }
|
||||||
s.source_files = "SwiftValidator/**/*.swift"
|
s.source_files = "SwiftValidator/**/*.swift"
|
||||||
s.exclude_files = "Validator/AppDelegate.swift"
|
s.exclude_files = "Validator/AppDelegate.swift"
|
||||||
s.frameworks = ['Foundation', 'UIKit']
|
s.frameworks = ['Foundation', 'UIKit']
|
||||||
|
|
|
||||||
|
|
@ -13,13 +13,21 @@ import UIKit
|
||||||
*/
|
*/
|
||||||
@objc public protocol ValidationDelegate {
|
@objc public protocol ValidationDelegate {
|
||||||
/**
|
/**
|
||||||
This method will be called on delegate object when validation is successful.
|
This delegate method will be called on delegate object when validation is successful.
|
||||||
- returns: No return value.
|
- returns: No return value.
|
||||||
*/
|
*/
|
||||||
func validationSuccessful()
|
func validationSuccessful()
|
||||||
/**
|
/**
|
||||||
This method will be called on delegate object when validation fails.
|
This delegae method will be called on delegate object when validation fails.
|
||||||
- returns: No return value.
|
- returns: No return value.
|
||||||
*/
|
*/
|
||||||
func validationFailed(errors: [UITextField:ValidationError])
|
func validationFailed(errors: [UITextField:ValidationError])
|
||||||
|
/**
|
||||||
|
This delegate method is called on fields that require remote validation.
|
||||||
|
- parameter text: String to is sent to server to be validated.
|
||||||
|
- parameter urlString: String of url endpoint that will be used to validate text.
|
||||||
|
- parameter completion: closure that holds the result of the server validation request. Should be set to true if server validation was a success. Should return false if server validation failed.
|
||||||
|
- returns: No return value.
|
||||||
|
*/
|
||||||
|
optional func remoteValidationRequest(text: String, urlString: String, completion:(result: Bool) -> Void)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,17 +11,19 @@ import UIKit
|
||||||
/**
|
/**
|
||||||
Class that makes `Validator` objects. Should be added as a parameter to ViewController that will display
|
Class that makes `Validator` objects. Should be added as a parameter to ViewController that will display
|
||||||
validation fields.
|
validation fields.
|
||||||
*/
|
*/
|
||||||
public class Validator {
|
public class Validator {
|
||||||
/// Dictionary to hold all fields (and accompanying rules) that will undergo validation.
|
/// Dictionary to hold all fields (and accompanying rules) that will undergo validation.
|
||||||
public var validations = [UITextField:ValidationRule]()
|
public var validations = [UITextField:ValidationRule]()
|
||||||
/// Dictionary to hold fields (and accompanying errors) that were unsuccessfully validated.
|
/// Dictionary to hold fields (and accompanying errors) that were unsuccessfully validated.
|
||||||
public var errors = [UITextField:ValidationError]()
|
public var errors = [UITextField:ValidationError]()
|
||||||
/// Variable that holds success closure to display positive status of field.
|
/// Variable that holds success closure to display positive status of field.
|
||||||
|
public var delegate: ValidationDelegate?
|
||||||
private var successStyleTransform:((validationRule:ValidationRule)->Void)?
|
private var successStyleTransform:((validationRule:ValidationRule)->Void)?
|
||||||
/// Variable that holds error closure to display negative status of field.
|
/// Variable that holds error closure to display negative status of field.
|
||||||
private var errorStyleTransform:((validationError:ValidationError)->Void)?
|
private var errorStyleTransform:((validationError:ValidationError)->Void)?
|
||||||
/// - returns: An initialized object, or nil if an object could not be created for some reason that would not result in an exception.
|
/// - returns: An initialized object, or nil if an object could not be created for some reason that would not result in an exception.
|
||||||
|
private var completedValidationsCount: Int = 0
|
||||||
public init(){}
|
public init(){}
|
||||||
|
|
||||||
// MARK: Private functions
|
// MARK: Private functions
|
||||||
|
|
@ -53,6 +55,94 @@ public class Validator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
This method is used to validate all fields registered to Validator. If validation is unsuccessful,
|
||||||
|
field gets added to errors dictionary. Completion closure is used to validator know when all fields
|
||||||
|
have undergone validation attempt.
|
||||||
|
- parameter completion: Bool that is set to true when all fields have experienced validation attempt.
|
||||||
|
- returns: No return value.
|
||||||
|
*/
|
||||||
|
private func validateAllFields(completion: (finished: Bool) -> Void) {
|
||||||
|
errors = [:]
|
||||||
|
|
||||||
|
for (textField, rule) in validations {
|
||||||
|
if rule.remoteInfo != nil {
|
||||||
|
validateRemoteField(textField, callback: { error -> Void in
|
||||||
|
self.completedValidationsCount = self.completedValidationsCount + 1
|
||||||
|
if self.completedValidationsCount == self.validations.count {
|
||||||
|
// Sends validation back to validate()
|
||||||
|
completion(finished: true)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
validateRegularField(textField)
|
||||||
|
self.completedValidationsCount = self.completedValidationsCount + 1
|
||||||
|
if completedValidationsCount == validations.count {
|
||||||
|
// Sends validation back to validate()
|
||||||
|
completion(finished: true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
This method is used to validate a field that will need to also be validated via remote request.
|
||||||
|
- parameter textField: TextField of field that is being validated.
|
||||||
|
- parameter completion: Closure that holds the status of textField's validation. Is set to true
|
||||||
|
after remote validation has ended, regardless of whether the validation was a success or failure.
|
||||||
|
- returns: No return value.
|
||||||
|
*/
|
||||||
|
public func validateRemoteField(textField: UITextField, callback: (error: ValidationError?) -> Void) {
|
||||||
|
if let fieldRule = validations[textField] {
|
||||||
|
// Carry on with validation only if regular validation passed
|
||||||
|
if self.validateRegularField(fieldRule.textField) {
|
||||||
|
delegate!.remoteValidationRequest?(textField.text!, urlString: fieldRule.remoteInfo!.urlString, completion: { result -> Void in
|
||||||
|
if result {
|
||||||
|
if let transform = self.successStyleTransform {
|
||||||
|
transform(validationRule: fieldRule)
|
||||||
|
}
|
||||||
|
callback(error: nil)
|
||||||
|
} else {
|
||||||
|
// Stop validation because remote validation failed
|
||||||
|
// Validation Failed on remote call
|
||||||
|
let error = ValidationError(textField: fieldRule.textField, errorLabel: fieldRule.errorLabel, error: fieldRule.remoteInfo!.error)
|
||||||
|
self.errors[fieldRule.textField] = error
|
||||||
|
if let transform = self.errorStyleTransform {
|
||||||
|
transform(validationError: error)
|
||||||
|
}
|
||||||
|
callback(error: error)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Method used to validate a regular field (non-remote).
|
||||||
|
- parameter: TextField of field that is undergoing validation
|
||||||
|
- returns: A Bool that represents whether the validation was a success or failure, returns true for the
|
||||||
|
former and false for the latter.
|
||||||
|
*/
|
||||||
|
private func validateRegularField(textField: UITextField) -> Bool {
|
||||||
|
if let fieldRule = validations[textField] {
|
||||||
|
if let error = fieldRule.validateField() {
|
||||||
|
errors[textField] = error
|
||||||
|
if let transform = self.errorStyleTransform {
|
||||||
|
transform(validationError: error)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
} else {
|
||||||
|
if let transform = self.successStyleTransform {
|
||||||
|
if fieldRule.remoteInfo == nil {
|
||||||
|
transform(validationRule: fieldRule)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// MARK: Public functions
|
// MARK: Public functions
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -100,9 +190,9 @@ public class Validator {
|
||||||
- parameter textField: field that is to be validated.
|
- parameter textField: field that is to be validated.
|
||||||
- parameter Rule: An array which holds different rules to validate against textField.
|
- parameter Rule: An array which holds different rules to validate against textField.
|
||||||
- returns: No return value
|
- returns: No return value
|
||||||
*/
|
*/
|
||||||
public func registerField(textField:UITextField, rules:[Rule]) {
|
public func registerField(textField:UITextField, rules:[Rule], remoteInfo: (String, String)? = nil) {
|
||||||
validations[textField] = ValidationRule(textField: textField, rules: rules, errorLabel: nil)
|
validations[textField] = ValidationRule(textField: textField, rules: rules, errorLabel: nil, remoteInfo: remoteInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -112,9 +202,9 @@ public class Validator {
|
||||||
- parameter errorLabel: A UILabel that holds error label data
|
- parameter errorLabel: A UILabel that holds error label data
|
||||||
- parameter rules: A Rule array that holds different rules that apply to said textField.
|
- parameter rules: A Rule array that holds different rules that apply to said textField.
|
||||||
- returns: No return value
|
- returns: No return value
|
||||||
*/
|
*/
|
||||||
public func registerField(textField:UITextField, errorLabel:UILabel, rules:[Rule]) {
|
public func registerField(textField:UITextField, errorLabel:UILabel, rules:[Rule], remoteInfo: (String, String)? = nil) {
|
||||||
validations[textField] = ValidationRule(textField: textField, rules:rules, errorLabel:errorLabel)
|
validations[textField] = ValidationRule(textField: textField, rules:rules, errorLabel:errorLabel, remoteInfo: remoteInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -122,7 +212,7 @@ public class Validator {
|
||||||
|
|
||||||
- parameter textField: field used to locate and remove textField from validator.
|
- parameter textField: field used to locate and remove textField from validator.
|
||||||
- returns: No return value
|
- returns: No return value
|
||||||
*/
|
*/
|
||||||
public func unregisterField(textField:UITextField) {
|
public func unregisterField(textField:UITextField) {
|
||||||
validations.removeValueForKey(textField)
|
validations.removeValueForKey(textField)
|
||||||
errors.removeValueForKey(textField)
|
errors.removeValueForKey(textField)
|
||||||
|
|
@ -132,7 +222,7 @@ public class Validator {
|
||||||
This method checks to see if all fields in validator are valid.
|
This method checks to see if all fields in validator are valid.
|
||||||
|
|
||||||
- returns: No return value.
|
- returns: No return value.
|
||||||
*/
|
*/
|
||||||
public func validate(delegate:ValidationDelegate) {
|
public func validate(delegate:ValidationDelegate) {
|
||||||
|
|
||||||
self.validateAllFields()
|
self.validateAllFields()
|
||||||
|
|
@ -146,12 +236,30 @@ public class Validator {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
This method validates all fields in validator and sets any errors to errors parameter of callback.
|
This method attempts to validate all fields registered to Validator().
|
||||||
|
- returns: No return value.
|
||||||
|
*/
|
||||||
|
public func validate() {
|
||||||
|
self.validateAllFields { finished -> Void in
|
||||||
|
if self.errors.isEmpty {
|
||||||
|
// call success method if it's implemented
|
||||||
|
self.delegate!.validationSuccessful()
|
||||||
|
} else {
|
||||||
|
// call failure method if it's implemented
|
||||||
|
self.delegate!.validationFailed(self.errors)
|
||||||
|
}
|
||||||
|
// set number of completed validations back to 0
|
||||||
|
self.completedValidationsCount = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
This method validates all fields in validator and sets any errors to errors parameter of closure.
|
||||||
|
|
||||||
- parameter callback: A closure which is called with errors, a dictionary of type UITextField:ValidationError.
|
- parameter callback: A closure which is called with errors, a dictionary of type UITextField:ValidationError.
|
||||||
|
|
||||||
- returns: No return value.
|
- returns: No return value.
|
||||||
*/
|
*/
|
||||||
public func validate(callback:(errors:[UITextField:ValidationError])->Void) -> Void {
|
public func validate(callback:(errors:[UITextField:ValidationError])->Void) -> Void {
|
||||||
|
|
||||||
self.validateAllFields()
|
self.validateAllFields()
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,9 @@ public class ValidationRule {
|
||||||
public var errorLabel:UILabel?
|
public var errorLabel:UILabel?
|
||||||
/// the rules of the field
|
/// the rules of the field
|
||||||
public var rules:[Rule] = []
|
public var rules:[Rule] = []
|
||||||
|
/// tuple that holds remote validatin info
|
||||||
|
public var remoteInfo: (urlString: String, error: String)?
|
||||||
|
//public var remoteURLString: String?
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Initializes `ValidationRule` instance with text field, rules, and errorLabel.
|
Initializes `ValidationRule` instance with text field, rules, and errorLabel.
|
||||||
|
|
@ -27,10 +30,12 @@ public class ValidationRule {
|
||||||
- parameter rules: array of Rule objects, which text field will be validated against.
|
- parameter rules: array of Rule objects, which text field will be validated against.
|
||||||
- returns: An initialized `ValidationRule` object, or nil if an object could not be created for some reason that would not result in an exception.
|
- returns: An initialized `ValidationRule` object, or nil if an object could not be created for some reason that would not result in an exception.
|
||||||
*/
|
*/
|
||||||
public init(textField: UITextField, rules:[Rule], errorLabel:UILabel?){
|
|
||||||
|
public init(textField: UITextField, rules:[Rule], errorLabel:UILabel? = nil, remoteInfo: (String, String)? = nil){
|
||||||
self.textField = textField
|
self.textField = textField
|
||||||
self.errorLabel = errorLabel
|
self.errorLabel = errorLabel
|
||||||
self.rules = rules
|
self.rules = rules
|
||||||
|
self.remoteInfo = remoteInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,40 @@ class SwiftValidatorTests: XCTestCase {
|
||||||
|
|
||||||
let ERROR_LABEL = UILabel()
|
let ERROR_LABEL = UILabel()
|
||||||
|
|
||||||
|
let URL_STRING = "http://localhost:8000/emails/"
|
||||||
|
let EMAIL_TAKEN_MESSAGE = "Email already taken"
|
||||||
|
|
||||||
|
class FailureRemoteValidationViewController: UIViewController, ValidationDelegate {
|
||||||
|
func validationSuccessful() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func validationFailed(errors: [UITextField : ValidationError]) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func remoteValidationRequest(text: String, urlString: String, completion: (result: Bool) -> Void) {
|
||||||
|
completion(result: false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class SuccessRemoteValidationViewController: UIViewController, ValidationDelegate {
|
||||||
|
func validationSuccessful() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func validationFailed(errors: [UITextField : ValidationError]) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func remoteValidationRequest(text: String, urlString: String, completion: (result: Bool) -> Void) {
|
||||||
|
completion(result: true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let REGISTER_FAILURE_REMOTE_VALIDATION_DELEGATE = FailureRemoteValidationViewController()
|
||||||
|
let REGISTER_SUCCESS_REMOTE_VALIDATION_DELEGATE = SuccessRemoteValidationViewController()
|
||||||
|
|
||||||
override func setUp() {
|
override func setUp() {
|
||||||
super.setUp()
|
super.setUp()
|
||||||
// Put setup code here. This method is called before the invocation of each test method in the class.
|
// Put setup code here. This method is called before the invocation of each test method in the class.
|
||||||
|
|
@ -370,6 +404,44 @@ class SwiftValidatorTests: XCTestCase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Used to test validation success on a single field that has remote validation
|
||||||
|
func testValidateSuccessSingleRemoteField() {
|
||||||
|
REGISTER_TXT_FIELD.text = VALID_EMAIL
|
||||||
|
REGISTER_VALIDATOR.registerField(REGISTER_TXT_FIELD, errorLabel: ERROR_LABEL, rules: [EmailRule()], remoteInfo: (urlString: URL_STRING, error: EMAIL_TAKEN_MESSAGE))
|
||||||
|
REGISTER_VALIDATOR.delegate = REGISTER_SUCCESS_REMOTE_VALIDATION_DELEGATE
|
||||||
|
REGISTER_VALIDATOR.validateRemoteField(REGISTER_TXT_FIELD) { error -> Void in
|
||||||
|
XCTAssertNil(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Used to test validation failure on a single field that has remote validation
|
||||||
|
func testValidateFailureSingleRemoteField() {
|
||||||
|
REGISTER_TXT_FIELD.text = VALID_EMAIL
|
||||||
|
REGISTER_VALIDATOR.registerField(REGISTER_TXT_FIELD, errorLabel: ERROR_LABEL, rules: [EmailRule()], remoteInfo: (urlString: URL_STRING, error: EMAIL_TAKEN_MESSAGE))
|
||||||
|
REGISTER_VALIDATOR.delegate = REGISTER_FAILURE_REMOTE_VALIDATION_DELEGATE
|
||||||
|
REGISTER_VALIDATOR.validateRemoteField(REGISTER_TXT_FIELD) { error -> Void in
|
||||||
|
XCTAssertNotNil(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Used to test remote validation success
|
||||||
|
func testValidationSuccessOnRemoteSuccess() {
|
||||||
|
REGISTER_TXT_FIELD.text = VALID_EMAIL
|
||||||
|
REGISTER_VALIDATOR.registerField(REGISTER_TXT_FIELD, errorLabel: ERROR_LABEL, rules: [EmailRule()], remoteInfo: (urlString: URL_STRING, error: EMAIL_TAKEN_MESSAGE))
|
||||||
|
REGISTER_VALIDATOR.delegate = REGISTER_SUCCESS_REMOTE_VALIDATION_DELEGATE
|
||||||
|
REGISTER_VALIDATOR.validate()
|
||||||
|
XCTAssert(REGISTER_VALIDATOR.errors.count == 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Used to test remote validation failure
|
||||||
|
func testValidationFailOnRemoteFailure() {
|
||||||
|
REGISTER_TXT_FIELD.text = VALID_EMAIL
|
||||||
|
REGISTER_VALIDATOR.registerField(REGISTER_TXT_FIELD, errorLabel: ERROR_LABEL, rules: [EmailRule()], remoteInfo: (urlString: URL_STRING, error: EMAIL_TAKEN_MESSAGE))
|
||||||
|
REGISTER_VALIDATOR.delegate = REGISTER_FAILURE_REMOTE_VALIDATION_DELEGATE
|
||||||
|
REGISTER_VALIDATOR.validate()
|
||||||
|
XCTAssert(REGISTER_VALIDATOR.errors.count == 1, "There is at least one error")
|
||||||
|
}
|
||||||
|
|
||||||
// MARK: Validate error field gets it's text set to the error, if supplied
|
// MARK: Validate error field gets it's text set to the error, if supplied
|
||||||
|
|
||||||
func testNoErrorMessageSet() {
|
func testNoErrorMessageSet() {
|
||||||
|
|
|
||||||
|
|
@ -50,33 +50,58 @@ class ViewController: UIViewController , ValidationDelegate, UITextFieldDelegate
|
||||||
})
|
})
|
||||||
|
|
||||||
validator.registerField(fullNameTextField, errorLabel: fullNameErrorLabel , rules: [RequiredRule(), FullNameRule()])
|
validator.registerField(fullNameTextField, errorLabel: fullNameErrorLabel , rules: [RequiredRule(), FullNameRule()])
|
||||||
validator.registerField(emailTextField, errorLabel: emailErrorLabel, rules: [RequiredRule(), EmailRule()])
|
validator.registerField(emailTextField, errorLabel: emailErrorLabel, rules: [RequiredRule(), EmailRule()], remoteInfo: (urlString: "http://localhost:8000/emails/", error: "Email already in use"))
|
||||||
validator.registerField(emailConfirmTextField, errorLabel: emailConfirmErrorLabel, rules: [RequiredRule(), ConfirmationRule(confirmField: emailTextField)])
|
validator.registerField(emailConfirmTextField, errorLabel: emailConfirmErrorLabel, rules: [RequiredRule(), ConfirmationRule(confirmField: emailTextField)])
|
||||||
validator.registerField(phoneNumberTextField, errorLabel: phoneNumberErrorLabel, rules: [RequiredRule(), MinLengthRule(length: 9)])
|
validator.registerField(phoneNumberTextField, errorLabel: phoneNumberErrorLabel, rules: [RequiredRule(), MinLengthRule(length: 9)])
|
||||||
validator.registerField(zipcodeTextField, errorLabel: zipcodeErrorLabel, rules: [RequiredRule(), ZipCodeRule()])
|
validator.registerField(zipcodeTextField, errorLabel: zipcodeErrorLabel, rules: [RequiredRule(), ZipCodeRule()])
|
||||||
|
validator.delegate = self
|
||||||
}
|
}
|
||||||
|
|
||||||
@IBAction func submitTapped(sender: AnyObject) {
|
@IBAction func submitTapped(sender: AnyObject) {
|
||||||
print("Validating...")
|
print("Validating...")
|
||||||
validator.validate(self)
|
validator.validate()
|
||||||
|
}
|
||||||
|
|
||||||
|
func simulateRemoteRequest(seconds: Int64, completion: (result: Bool) -> Void) {
|
||||||
|
print("Simulating \(seconds) second server request...")
|
||||||
|
// Set number of seconds before "request" is finished
|
||||||
|
let triggerTime = (Int64(NSEC_PER_SEC) * seconds)
|
||||||
|
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, triggerTime), dispatch_get_main_queue(), { () -> Void in
|
||||||
|
// For example purposes, if user does not enter David Patterson as full name,
|
||||||
|
// the email they tried will be already taken
|
||||||
|
if self.fullNameTextField.text! == "David Patterson" {
|
||||||
|
completion(result: true)
|
||||||
|
} else {
|
||||||
|
completion(result: false)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func hideKeyboard(){
|
||||||
|
self.view.endEditing(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: ValidationDelegate Methods
|
// MARK: ValidationDelegate Methods
|
||||||
|
|
||||||
func validationSuccessful() {
|
func validationSuccessful() {
|
||||||
print("Validation Success!")
|
print("Validation Success!")
|
||||||
let alert = UIAlertController(title: "Success", message: "You are validated!", preferredStyle: UIAlertControllerStyle.Alert)
|
let alert = UIAlertController(title: "Success", message: "You are validated, \(fullNameTextField.text!)!", preferredStyle: UIAlertControllerStyle.Alert)
|
||||||
let defaultAction = UIAlertAction(title: "OK", style: .Default, handler: nil)
|
let defaultAction = UIAlertAction(title: "OK", style: .Default, handler: nil)
|
||||||
alert.addAction(defaultAction)
|
alert.addAction(defaultAction)
|
||||||
self.presentViewController(alert, animated: true, completion: nil)
|
self.presentViewController(alert, animated: true, completion: nil)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func validationFailed(errors:[UITextField:ValidationError]) {
|
func validationFailed(errors:[UITextField:ValidationError]) {
|
||||||
print("Validation FAILED!")
|
print("Validation FAILED!", validator.errors.count)
|
||||||
}
|
}
|
||||||
|
|
||||||
func hideKeyboard(){
|
func remoteValidationRequest(text: String, urlString: String, completion: (result: Bool) -> Void) {
|
||||||
self.view.endEditing(true)
|
simulateRemoteRequest(2) { result -> Void in
|
||||||
|
// Set result to true if field was validated server-side
|
||||||
|
// Set to false if field was not validated server-side
|
||||||
|
completion(result: result)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: Validate single field
|
// MARK: Validate single field
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue