adamwaite / validator Goto Github PK
View Code? Open in Web Editor NEWDrop in user input validation for your iOS apps.
License: MIT License
Drop in user input validation for your iOS apps.
License: MIT License
Shall the API align to both say enabled?
This was changed in https://github.com/adamwaite/Validator/blob/47d675b9a864f6aff91c3c45e3256147896d0556/Validator/Validator/UIKit%2BValidator/UITextField%2BValidator.swift
open func validateOnInputChange(enabled: Bool) {
open func validateOnEditingEnd(validationEnabled: Bool) {
Hello All,
I have a really quick question, is there an example for using the require function? I've tried implementing and once I use
let stringRequiredRule = ValidationRuleRequired<String?>(failureError: ValidationError(message: "๐ซ"))
stringCell.validationRuleSet?.add(rule: stringRequiredRule)
I get the following error
Generic parameter 'R' could not be inferred
import Validator
extension String: Error {}
extension ValidationRuleSet {
static var email: ValidationRuleSet<String> {
return ValidationRuleSet<String>(rules: [
ValidationRuleLength(min: 1, max: Int.max, error: R.string.localizable.authEmptyEmail()),
ValidationRulePattern(pattern: EmailValidationPattern.standard,
error:R.string.localizable.authInvalidEmail())
])
}
}
I'm trying to create a rule set for UITextField, but it says that Cannot convert value of type '[Any]' to expected argument type '[_]'
. What's wrong?
I added the module via Carthage. But I get this error:
Module file's minimum deployment target is ios9.0 v9.0: /Users/*/Carthage/Build/iOS/Validator.framework/Modules/Validator.swiftmodule/x86_64.swiftmodule
Isn't it possible to target on iOS 8?
With the use of Self in the ValidationRuleSet struct, we cannot mix rules in the current inits when one rule has an associated type and others do not. Should there be an init method so we can pass in the type erasure form of the rule and open up the possibly of passing [AnyValidationRule] instead of having to .add() for each and every rule?
I entered 'a dddd' and there seems no error.
In AJWValidator there are two properties of type NSMutableArray, which are declared as copy. If one would use these properties to set the respective arrays it would cause a problem which most likely will result in a crash:
self.mutableErrorMessages = [NSMutableArray array];
[self.rules addObject:@"test"];
/*Preceding line results in: Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArrayI addObject:]: unrecognized selector sent to instance*/
Due to the usage of copy, the setter would copy the given NSMutableArray into an IMMUTABLE NSArray instance hence causing every call of NSMutableArray specific methods to throw an NSInvalidArgumentException.
This rule will always trigger when String? is nil. If the string is nil and min >= 0 then this should probably treat the nil string as an empty string.
input?.characters.count >= min
false
When I add Validator to my project, the "Sent Events" section disappears from my Storyboard's Connections Inspector/Menu. I'm a bit of a GUI weenie so I was alarmed at first. I know that I can hand code Target/Action connections, so I calmed down after a while. But still, I'd still like to mix both Validator and Storyboard managed Target/Action connections.
Is that possible?
Why did the the "Sent Events" section disappear? I sense an opportunity to learn about the deeper workings of Storyboard, hand registration of target/actions for particular events.
Is it possible to have a Validator field with a regex mask? like "xxx-xxx-xxxx"
I want it automatically adds the extra characters. If the user inputs "1234567890" it shows "123-456-7890"
@adamwaite
As we have addRule api for adding rule to input values.For same can we have removeRule API?
Hi Adam,
My team and I recently added a postcode validation pattern to Validator and have encountered the following issue when a validation pattern has a number of options. For example, UK postcodes can be provided lowercase, uppercase, with a space or without a space. Currently, we could provide a separate enum case
for each according to the validation required, however, this quickly becomes unwieldy.
An alternative is to restructure the ValidationPattern
enum to handle associated values and return the appropriate regex as follows:
enum PostcodeOptions {
case AllowsOptionalSpace
}
enum ValidationPattern {
case EmailAddress
case ContainsNumber
case ContainsCapital
case ContainsLowercase
case UKPostcode(options: [PostcodeOptions])
var pattern: String {
switch self {
case .EmailAddress:
return "^[_A-Za-z0-9-+]+(\\.[_A-Za-z0-9-+]+)*@[A-Za-z0-9-]+(\\.[A-Za-z0-9-]+)*(\\.[A-Za-zโโ]{2,})$"
case .ContainsNumber:
return ".*\\d.*"
case .ContainsCapital:
return "^.*?[A-Z].*?$"
case .ContainsLowercase:
return "^.*?[a-z].*?$"
case .UKPostcode(let options):
let optionalSpace = options.contains(.AllowsOptionalSpace) ? "[ ]?" : " "
return "(GIR 0AA)|((([A-Z-[QVX]][0-9][0-9]?)|(([A-Z-[QVX]][A-Z-[IJZ]][0-9][0-9]?)|(([A-Z-[QVX]][0-9][A-HJKPSTUW])|([A-Z-[QVX]][A-Z-[IJZ]][0-9][ABEHMNPRVWXY]))))\(optionalSpace)[0-9][A-Z-[CIKMOV]]{2})"
}
}
}
You could also group the string patterns .ContainsNumber
, .ContainsCapital
, .ContainsLowercase
into their own options group and construct the regex in a .String
case creating one validation rule from multiple options.
I understand this proposal would change how users currently create validations and so wanted to first sound out your view on the value of this.
Many thanks
Hello,
Great library! I have really enjoyed using it so far to validate UITextField's, it was painless. I was wondering how one could validate for a UITextView. After reading the readme, I came up with:
extension UITextView: ValidatableInterfaceElement {
public typealias InputType = String
var inputValue: String { return text ?? "" }
public func validateOnInputChange(validationEnabled: Bool) {
switch validationEnabled {
case true: addTarget(self, action: "validateInputChange:", forControlEvents: .EditingChanged)
case false: removeTarget(self, action: "validateInputChange:", forControlEvents: .EditingChanged)
}
}
@objc private func validateInputChange(sender: UITextView) {
sender.validate()
}
}
which is probably very wrong, because it is just a copy and paste, and the compiler gives these errors:
Type 'UITextView' does not conform to protocol 'ValidatableInterfaceElement'
Use of unresolved identifier addTarget
Use of unresolved identifier removeTarget
These errors make sense, because UITextView does not have addTarget/removeTarget methods. Sadly, my Swift-fu and Obj-C-fu are laughable, but it seems possible as in the following Stackoverflow question:
http://stackoverflow.com/questions/17497891/how-to-make-a-uitextview-call-the-addtarget-method
I tried making my UIViewController that has the UITextView implement UITextViewDelegate, and then:
func textViewDidChange(textView: UITextView) {
keyText = textView.text
}
but I am not sure how to wire this all up and make it work. Any ideas/suggestions? Also this could be an opportunity to add to the library, like UITextView+Validator.swift, as it would seem to be a pretty common thing, at least I would think so :).
Thanks very much.
First of all: Great job on this project! I love using it!
I was wondering if it is intentional that validationRuleSets and validationHandler are strongly referenced and that they cannot be set to nil. I'm trying to get my code as efficient as possible and this prevents ViewController from being deinitialized.
Thanks in advance
Hello,
It appears that all validation is completed inline. Is there a way to double confirm validation on submit of a form for example.
I want to either check the current validation status or revalid against the same rule again to confirm. Otherwise when a submit button is pressed there might be multiple rows still in a bad state.
Thanks
I`m getting this error when I add this repo in my Cartfile. like this:
github "adamwaite/Validator"
this is the error:
`Failed to discover shared schemes in project Example.xcodeproj โ either the project does not have any shared schemes, or xcodebuild timed out.
If you believe this to be a project configuration error, please file an issue with the maintainers at https://github.com/adamwaite/Validator/issues/new`
What can I do?
when i have a validationrulest and add a required rule and others (e.g. email), then only email is validated, the required rule is ignored.
i think it is because string cannot be nil... why dont you check for empty string if type is string in the required rule?
Is there any way to check if a specific field has failed the validation?
I have a UIView under each textfield, and I want to color the UIView red under the textfield that fails validation.
And big thanks for sharing this lib!
is this class not contain validation for url ?
Is there a way to make a validation rule for numbers only? I see contains digits, but looking to have a textfield that can only accept numbers.
Thanks
Could you add good regex pattern for international mobile as well as UIextField, which automatically format phone humber (like PhoneNumberKit)?
Hi there,
may anyone have knowledge to add Carthage support for this great library ?
It would be great since Carthage become popular nowadays.
Thanks.
Protocol 'ValidatableInterfaceElement' can only be used as a generic constraint because it has Self or associated type requirements.
So I cannot check if a element is a ValidatableInterfaceElement and has a validate method on it?
Greetings again, one final question, I noticed that in the pull requests there use to exist a Date Range validation rule. Was this ever merged into the main library?
What is the best way to handle Error priority so that when multiple rules are hit, we can easily identify the priority of the rules? The point of validation does not know priority of the validation in a ValidationRuleSet.
Hi,
Why you set project target on iOS7?
I was really suprise when cocoapods told me :
"[!] The platform of the target Pods
(iOS 6.0) is not compatible with ALPValidator (0.0.2)
which has a minimum requirement of iOS 7.0."
Are you use any method iOS7 only?
I guess such a validation rule is pretty common.
Although this could be as simple as ValidationRuleLength(min: 1, failureError: error)
having a shortcut method for it would be awesome.
Useful and fast enhancement
Really nice library :)
It would be great to be able to set a priority of dependencies. At the moment if setting the required and min length validator for example, it will return errors for both. It would be nice if you could set that it will only validate min length if required is already validated. This becomes especially useful with remote validation i.e. don't bother hammering the server if the instance is not at least 5 chars. Make sense or is there a way of doing similar already that I totally missed (without doing a bunch of unique validators stuck inside an if isvalid condition)?
I'm getting a lot of Result of call to 'validate()' is unused
warnings.
This could just be how I've implemented Validator in my app, but if not, we should add @discardableResult
to the validate function to silence these warnings. I'm happy to make the changes if others think this is the right way to go.
hi, validator will upgrade the code to swift4?
instead of "case invalid([Error])" should be "case invalid([ValidationError])"
Hi!
The currently released version still has deprecation warnings in it because of things like associatedtype and new selector syntax. I've seen that there is a commit in master that fixes it, but I would like to ask when will it be available via a release? It is not too good to point to the master branch in a production code.
Thank you!
I was updating CocoaPods for one of my projects and ran into the following error:
Update all pods
Analyzing dependencies
Downloading dependencies
Installing ALPValidator (0.0.3)
[!] Pod::Executable remote update
error: cannot open FETCH_HEAD: Permission denied
I am pretty much a CocoaPod newbie, so I have no clue what this error means or whether it is something I can fix. Can you help me?
Explore 'rule' protocol over abstract rule interface
Just imagine a login page.
Enable the Login button only if the username and password both are correct.
This is an awesome project. A real treasure trove of Swift patterns for us newbies. I feel odd filing an issue for a general question. Maybe it would be a good idea to start up a Google Group, or something of that ilk?
Why differentiate between ValidationRule
and ValidationRuleSet
? I would have thought that ValidationRuleSet
would inherit from ValidationRule
. I'm sure that I'm missing some overriding pattern. TIA
dear adamwaite, why public_header_files exclude "ALPValidatorRule.h"?
i want to use rule then inherit and override something. in my xcode project (using Pods), i can't import ALPValidatorRule.h
could you update podsepc?
Is this a really good behaviour?
I have an array of text fields for UIViewController and I iterate over all and run validate()
and merging the result of the validation... But if there is no attached rules fatal error is thrown...
Personally, I would suggest returning .valid
if there is no rules attached to ValidatableInterfaceElement
instead of throwing fatal error. What do you think guys?
Hi @adamwaite ,
I am using Validator in my project.
Can you please help me in using custom rule in swift 3.0
Please check below code:
internal struct WhitespaceRule {
typealias InputType = String
var error: ValidationError = ValidationError(message: "")
init(message: String?) {
self.error = ValidationError(message: message ?? "Please enter valid character")
}
func validate(input: String?) -> Bool {
guard let nameText = input else { return false }
let trimmedString = nameText.trimmingCharacters(in: CharacterSet.whitespaces)
return !trimmedString.isEmpty
return true
}
}
But when I use this rule in my class like
nameRules.add(rule: WhitespaceRule(message: "Please enter an item name"))
It is giving me error argument type 'WhitespaceRule' does not conform to expected type 'ValidationRule'
}
Hello,
I've been working on a Swift 3.0 update but have run into a gnarly crash I don't know how to fix. If anyone else wants to pick it up from here and fix it, or point me in the right direction, I'd greatly appreciate it!
I think I've tracked down the issue to objc_getAssociatedObject
receiving an object that can't be turned into a ValidationRuleSet
, but I'm not 100% sure on that. I am pretty sure that the bug is something in ValidatableInterfaceElement.swift
though.
I just did a Pod Update and my build now gets the error:
/Users/gavin/montherly/Montherly/Pods/ALPValidator/ALPValidator/ALPValidator.h:31:9: 'UIView+ALPValidator.h' file not found
I checked the Pod file and noticed it in fact was not included (but did notice it in this repo) - was there a mistake with the cocoapod?
In README you have
let stringRequiredRule = ValidationRuleRequired<String?>(error: someValidationErrorType)
let floatRequiredRule = ValidationRuleRequired<Float?>(error: someValidationErrorType)
If you specify you rule type as optional, you will get double optionals inside validate method and it will always evaluate input as valid, making the rule useless. (Input to validate method is already specified as Optional of generic type, so for String? type you will then get String?? inside the method)
It seems that I can only register one validator. Is the thinking that I register my own custom target/action if I need such customization?
Hi @adamwaite,
public func validate() -> ValidationResult {
guard let attachedRules = validationRules else { fatalError("Validator Error: attempted to validate without attaching rules") }
return validate(rules: attachedRules)
}
as ValidationResult is return type and its not optional so when validationRules is coming nil then guard statement doesn't working properly because not returning anything.
Could anyone look into this.
Hello!
I just started using this framework, which is very cool and flexible ๐
I wanted to raise a point.
There is no documentation on any method/class in this project.
This is very cumbersome because it forces me (or any new user) to read the entire source code to understand why there is a specific parameter, or what are the other methods that are not documented in the README etc..
For example I had to look for validateOnEditingEnd
which is exactly what I need, but I had to check the source code to be sure,
while some documentation would let me do the same thing from my editor, which is the purpose of using a framework instead of writing myself the whole code
just my 2cents
I am not able to use the library in pure ObjectiveC code.
Isn't @objc missing?
/**
Initializes a `ValidationRulePattern` with a regular expression in string
format, and an error describing a failed
validation.
- Parameters:
- pattern: A regular expression in string format to evaluate an input
against.
- error: An error describing a failed validation.
*/
public init(pattern: String, error: Error) {
self.pattern = pattern
self.error = error
}
But internally it uses
public func validate(input: String?) -> Bool {
return NSPredicate(format: "SELF MATCHES %@", pattern).evaluate(with: input)
}
which is actually not the same with NSRegularExpression. NSPredicate mathches doesn't recognizes many patterns which NSRegularExpression does.
Validate on input change blows up for UITextField subclasses on this line with the following message:
Could not cast value of type 'Validator.(Box in _8483EA982F7B609A32A9F5BE7106930E)<(Validator.ValidationResult, MyApp.MyTextField) -> ()>' (0x1257e01b0) to 'Validator.(Box in _8483EA982F7B609A32A9F5BE7106930E)<(Validator.ValidationResult, UITextField) -> ()>' (0x1257e0330).
I came up with a workaround by overriding methods and properties declared by ValidatableInterfaceElement
in my MyTextField
, but it would be nice if I didn't need to do that :)
extension MyTextField {
typealias InputType = String
override var inputValue: String { return text ?? "" }
override func validateOnInputChange(validationEnabled: Bool) {
switch validationEnabled {
case true: addTarget(self, action: "validateInputChange:", forControlEvents: .EditingChanged)
case false: removeTarget(self, action: "validateInputChange:", forControlEvents: .EditingChanged)
}
}
@objc private func validateInputChange(sender: MyTextField) {
sender.validate()
}
}
Any ideas on how to approach this issue?
The regex requires a TLD, which isn't required in the email address spec[0]. There's been a lot written[1] about email regex that's too strict and I tend to agree that it's better to have false positives than false negatives, especially with a default validator. The regex actually fails a lot of valid email addresses (although most will likely rarely appear).
Here's a list[2] of valid email address the regex fails,
[0] https://tools.ietf.org/html/rfc2822#section-3.4
[1] Email spec in ABNF and also includes the regex implementation https://html.spec.whatwg.org/multipage/forms.html#valid-e-mail-address
[2] Taken from https://en.wikipedia.org/wiki/Email_address#Valid_email_addresses
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.