64

i am using the following code for phone number validation. But i am getting the following error. I cant able to proceed further. Help us to take it forward.

class PhoneNumberValidation: Validation {
    let PHONE_REGEX = "^\\d{3}-\\d{3}-\\d{4}$"

    func validate(value: String) -> (Bool, ValidationErrorType) {
        if let phoneTest = NSPredicate(format: "SELF MATCHES %@", PHONE_REGEX) {
            if phoneTest.evaluateWithObject(value) {
                return (true, .NoError)
            }
            return (false, .PhoneNumber)
        }
        return (false, .PhoneNumber)
    }
}

Error : swift:15:28: Bound value in a conditional binding must be of Optional type

Naresh
  • 16,698
  • 6
  • 112
  • 113
Saikumar
  • 877
  • 1
  • 9
  • 22
  • I cannot see an obvious error in your code. Which Xcode version are use using? On which line does the error occur? – Of course it would be better if you post an example that does not rely on other classes, so that we can just paste your code into Xcode and try to find the problem. – Martin R Jan 17 '15 at 10:19
  • It seems that you are using the using an outdated Xcode version. Update to Xcode 6.1.1 and your problem is gone. – Martin R Jan 17 '15 at 10:59

21 Answers21

98

Yes your Error is below in XCode 6.1

Xcode error screenshot

This error is occurs because of if conditional have to Bool return type, but in Your if condition Return type is NSPredicate so that you got error swift: Bound value in a conditional binding must be of Optional type you can solve as below.

    var phoneTest = NSPredicate(format: "SELF MATCHES %@", PHONE_REGEX)
         if phoneTest.evaluateWithObject(value) {
                  return (true, .NoError)
             }
                 return (false, .PhoneNumber)
            }

Email-Validations in Swift.

    func isValidEmail(testStr:String) -> Bool {
            print("validate emilId: \(testStr)")
            let emailRegEx = "^(?:(?:(?:(?: )*(?:(?:(?:\\t| )*\\r\\n)?(?:\\t| )+))+(?: )*)|(?: )+)?(?:(?:(?:[-A-Za-z0-9!#$%&’*+/=?^_'{|}~]+(?:\\.[-A-Za-z0-9!#$%&’*+/=?^_'{|}~]+)*)|(?:\"(?:(?:(?:(?: )*(?:(?:[!#-Z^-~]|\\[|\\])|(?:\\\\(?:\\t|[ -~]))))+(?: )*)|(?: )+)\"))(?:@)(?:(?:(?:[A-Za-z0-9](?:[-A-Za-z0-9]{0,61}[A-Za-z0-9])?)(?:\\.[A-Za-z0-9](?:[-A-Za-z0-9]{0,61}[A-Za-z0-9])?)*)|(?:\\[(?:(?:(?:(?:(?:[0-9]|(?:[1-9][0-9])|(?:1[0-9][0-9])|(?:2[0-4][0-9])|(?:25[0-5]))\\.){3}(?:[0-9]|(?:[1-9][0-9])|(?:1[0-9][0-9])|(?:2[0-4][0-9])|(?:25[0-5]))))|(?:(?:(?: )*[!-Z^-~])*(?: )*)|(?:[Vv][0-9A-Fa-f]+\\.[-A-Za-z0-9._~!$&'()*+,;=:]+))\\])))(?:(?:(?:(?: )*(?:(?:(?:\\t| )*\\r\\n)?(?:\\t| )+))+(?: )*)|(?: )+)?$"
            let emailTest = NSPredicate(format:"SELF MATCHES %@", emailRegEx)
            let result = emailTest.evaluateWithObject(testStr)
            return result
        } 

Use of Email-validation:

    if isValidEmail("kirit@gmail.com"){
            print("Validate EmailID")
        }
        else{
            print("invalide EmailID")
        }

Phone-Number Validation in Swift

    func validate(value: String) -> Bool {
            let PHONE_REGEX = "^\\d{3}-\\d{3}-\\d{4}$"
            let phoneTest = NSPredicate(format: "SELF MATCHES %@", PHONE_REGEX)
            let result = phoneTest.evaluate(with: value)
            return result
        }
gaussblurinc
  • 3,642
  • 9
  • 35
  • 64
Kirit Modi
  • 23,155
  • 15
  • 89
  • 112
  • Which Xcode version are you using? This does not compile in my Xcode 6.1.1 or 6.2beta3. – Also OP would benefit more from your answer if you *explained* the errors in his code, instead of simply posting your code. – Martin R Jan 17 '15 at 10:37
  • 1
    Your answer does not explain why OP gets an compiler error for his code. – Martin R Jan 17 '15 at 10:44
  • getting error near to "f let phoneTest = NSPredicate(format: "SELF MATCHES %@", PHONE_REGEX) {------------ Bound value in a conditional binding must be of Optional type"... – Saikumar Jan 17 '15 at 10:47
  • Sounds like the NSPredicate init function doesn't return an optional. Can anyone confirm that? If it doesn't you don't need to (in fact you cannot) bind that value in an if-let condition. – HAS Jan 17 '15 at 16:00
  • Note that `let emailRegEx = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}"` does not work for most of the new custom TLDs that can be longer than 4 characters. You can update it with `let emailRegEx = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}"` so there's no max length restriction for the TLD – Chris Wagner Feb 05 '16 at 00:07
  • It's just working for `.com`. Not working any other than that, like `.co.uk`. Can you please update? – Sohil R. Memon Mar 09 '16 at 11:48
  • @User9527 not updated formula for Email. Working abc@gmail..com = false – Kirit Modi Apr 23 '16 at 08:30
  • You should correct the Pincode validation in your blog. – Bhavin Ramani Aug 16 '16 at 06:13
  • @KiritModi I have just added this to validate zipcode: `let zipregex = "^[0-9]{6}$" let zipTest = NSPredicate(format: "SELF MATCHES %@", zipregex) let result = zipTest.evaluateWithObject(value) return result` But this will work only for indian zipcode. – Bhavin Ramani Aug 16 '16 at 06:27
  • Hmm. Good. I will update after get all country. can you get then say to me. – Kirit Modi Aug 16 '16 at 06:39
  • **Swift 4** -- func validate(phoneNumber: String) -> Bool { let PHONE_REGEX = "^\\d{3}-\\d{3}-\\d{4}$" let phoneTest = NSPredicate(format: "SELF MATCHES %@", PHONE_REGEX) let result = phoneTest.evaluate(with: phoneNumber) return result } – uplearned.com Nov 06 '17 at 05:37
  • Email validator fails by accepting email address of "loser@nowhere" as a valid email. – drewster Jun 28 '18 at 03:42
45

Swift 5 : Updated Solution(Swift 3 to 5)

//MARK: - Validation Extension

extension String {
    
    //To check text field or String is blank or not
    var isBlank: Bool {
        get {
            let trimmed = trimmingCharacters(in: CharacterSet.whitespaces)
            return trimmed.isEmpty
        }
    }
    
    //Validate Email
    
    var isEmail: Bool {
        do {
            let regex = try NSRegularExpression(pattern: "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}", options: .caseInsensitive)
            return regex.firstMatch(in: self, options: NSRegularExpression.MatchingOptions(rawValue: 0), range: NSMakeRange(0, self.count)) != nil
        } catch {
            return false
        }
    }
    
    var isAlphanumeric: Bool {
        return !isEmpty && range(of: "[^a-zA-Z0-9]", options: .regularExpression) == nil
    }
    
    //validate Password
    var isValidPassword: Bool {
        do {
            let regex = try NSRegularExpression(pattern: "^[a-zA-Z_0-9\\-_,;.:#+*?=!§$%&/()@]+$", options: .caseInsensitive)
            if(regex.firstMatch(in: self, options: NSRegularExpression.MatchingOptions(rawValue: 0), range: NSMakeRange(0, self.characters.count)) != nil){
                
                if(self.characters.count>=6 && self.count<=20){
                    return true
                }else{
                    return false
                }
            }else{
                return false
            }
        } catch {
            return false
        }
    }
}

use of Email Validation:

if(txtEmail.isEmail) {

}

Swift 2.0 Solution

Paste these line anywhere in code.(or in your Constant file)

extension String {
    
    //To check text field or String is blank or not
    var isBlank: Bool {
        get {
            let trimmed = stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceCharacterSet())
            return trimmed.isEmpty
        }
    }
    
    //Validate Email
    var isEmail: Bool {
        do {
            let regex = try NSRegularExpression(pattern: "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}", options: .CaseInsensitive)
            return regex.firstMatchInString(self, options: NSMatchingOptions(rawValue: 0), range: NSMakeRange(0, self.count)) != nil
        } catch {
            return false
        }
    }
    
    //validate PhoneNumber
    var isPhoneNumber: Bool {
        
        let charcter  = NSCharacterSet(charactersInString: "+0123456789").invertedSet
        var filtered:NSString!
        let inputString:NSArray = self.componentsSeparatedByCharactersInSet(charcter)
        filtered = inputString.componentsJoinedByString("")
        return  self == filtered
        
    }
}
Sourabh Sharma
  • 8,222
  • 5
  • 68
  • 78
20

Swift 4 & Swift 5:

func isValidPhone(phone: String) -> Bool {
        let phoneRegex = "^[0-9+]{0,1}+[0-9]{5,16}$"
        let phoneTest = NSPredicate(format: "SELF MATCHES %@", phoneRegex)
        return phoneTest.evaluate(with: phone)
    }

func isValidEmail(email: String) -> Bool {
        let emailRegEx = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,64}"
        let emailTest = NSPredicate(format:"SELF MATCHES %@", emailRegEx)
        return emailTest.evaluate(with: email)
    }

  • +1994423565 - Valid
  • ++1994423565 - Invalid
  • 01994423565 - Valid
  • 001994423565 - Valid
  • something@example.com - Valid
  • something@.com - Invalid
Rajesh Loganathan
  • 11,129
  • 4
  • 78
  • 90
  • 2
    `123456` is a valid number. Why? – Hemang Jan 22 '20 at 13:19
  • 1
    @Hemang it's easy, cause in regEx for number, this "^[0-9+]{0,1}" part is ^ - check only string start [0-9+] - characters we are allow (so all numbers and + sign is allowed) {0,1} - the number of allowed characters we are looking for, so it could zero, so plus sign is not necessary... Actually I would even update this answer by next regex for phone: "^[+]?+[0-9]{5,16}$" so we only checking if there is plus sign on start of the string, ? here is same as {0,1} – KostiaZzz Feb 26 '21 at 17:08
13

Maybe a better phone validator in Swift 2:

extension String {
    var isPhoneNumber: Bool {
        do {
            let detector = try NSDataDetector(types: NSTextCheckingType.PhoneNumber.rawValue)
            let matches = detector.matchesInString(self, options: [], range: NSMakeRange(0, self.characters.count))
            if let res = matches.first {
                return res.resultType == .PhoneNumber && res.range.location == 0 && res.range.length == self.characters.count
            } else {
                return false
            }
        } catch {
            return false
        }
    }
}
EPage_Ed
  • 1,173
  • 11
  • 11
  • 1
    For Swift 4.2 var isPhoneNumber: Bool { do { let detector = try NSDataDetector(types: NSTextCheckingResult.CheckingType.phoneNumber.rawValue) let matches = detector.matches(in: self, options: [], range: NSMakeRange(0, self.count)) if let res = matches.first { return res.resultType == .phoneNumber && res.range.location == 0 && res.range.length == self.count } else { return false } } catch { return false } } – Anil Kumar Dec 03 '18 at 10:03
  • 1
    Swift 5 var isValidPhone : Bool { do { let detector = try NSDataDetector(types: NSTextCheckingResult.CheckingType.phoneNumber.rawValue) let matches = detector.matches(in: self, options: [], range: NSMakeRange(0, self.count)) if let res = matches.first { return res.resultType == .phoneNumber && res.range.location == 0 && res.range.length == self.count } else { return false } } catch { return false } } – Amjad Tubasi Oct 19 '19 at 18:43
12

Swift 4+

You can use simplified regex "^[6-9]\\d{9}$"

^     #Match the beginning of the string
[6-9] #Match a 6, 7, 8 or 9
\\d   #Match a digit (0-9 and anything else that is a "digit" in the regex engine)
{9}   #Repeat the previous "\d" 9 times (9 digits)
$     #Match the end of the string

From Reference

Indian 10 Digit Mobile validation(can start with 6,7,8,9) -

extension String {
    var isValidContact: Bool {
        let phoneNumberRegex = "^[6-9]\\d{9}$"
        let phoneTest = NSPredicate(format: "SELF MATCHES %@", phoneNumberRegex)
        let isValidPhone = phoneTest.evaluate(with: self)
        return isValidPhone
    }
} 

Usage:-

print("9292929292".isValidContact)//true
print("5454545454".isValidContact)//false

For email validation you can check this

Jack
  • 13,571
  • 6
  • 76
  • 98
8

The following code works in xcode 6.3 beta

func isValidEmail(testStr:String) -> Bool {

   let emailRegEx = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}"
   let range = testStr.rangeOfString(emailRegEx, options:.RegularExpressionSearch)
   let result = range != nil ? true : false
   return result

}

how to use it:

Ex.

if isValidEmail(email.text) == false{
//your code here
}
TheRealRonDez
  • 2,807
  • 2
  • 30
  • 40
8

Updated version of iksnae's awesome answer. It's not a regex, but I think it's the best solution to validate all countries' phone numbers as it is smart enough to know if the country's phone extension code is valid as well.

extension String {
    public var validPhoneNumber: Bool {
        let types: NSTextCheckingResult.CheckingType = [.phoneNumber]
        guard let detector = try? NSDataDetector(types: types.rawValue) else { return false }
        if let match = detector.matches(in: self, options: [], range: NSMakeRange(0, self.count)).first?.phoneNumber {
            return match == self
        } else {
            return false
        }
    }
}

print("\("+96 (123) 456-0990".validPhoneNumber)") //returns false, smart enough to know if country phone code is valid as well 
print("\("+994 (123) 456-0990".validPhoneNumber)") //returns true because +994 country code is an actual country phone code
print("\("(123) 456-0990".validPhoneNumber)") //returns true
print("\("123-456-0990".validPhoneNumber)") //returns true
print("\("1234560990".validPhoneNumber)") //returns true
Samuel Folledo
  • 442
  • 6
  • 15
7

Swift 3:

private func validate(phoneNumber: String) -> Bool {
    let charcterSet  = NSCharacterSet(charactersIn: "+0123456789").inverted
    let inputString = phoneNumber.components(separatedBy: charcterSet)
    let filtered = inputString.joined(separator: "")
    return  phoneNumber == filtered
}
zumzum
  • 17,984
  • 26
  • 111
  • 172
6

Swift 3 Validate Email

class func validateEmail(email: String) -> Bool{

    let emailRegex = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,6}"

    return NSPredicate(format: "SELF MATCHES %@", emailRegex).evaluate(with: email)

}

Phone Number Validation

class func validatePhoneNumber(value: String) -> Bool {

    let PHONE_REGEX = "^\\d{3}-\\d{3}-\\d{4}$"
    let phoneTest = NSPredicate(format: "SELF MATCHES %@", PHONE_REGEX)
    let result =  phoneTest.evaluate(with: value)
    return result
}
shiju86.v
  • 667
  • 5
  • 10
5

Updated for Swift 3

extension String {
    var isPhoneNumber: Bool {
        do {
            let detector = try NSDataDetector(types: NSTextCheckingResult.CheckingType.phoneNumber.rawValue)
            let matches = detector.matches(in: self, options: [], range: NSMakeRange(0, self.characters.count))
            if let res = matches.first {
                return res.resultType == .phoneNumber && res.range.location == 0 && res.range.length == self.characters.count
            } else {
                return false
            }
        } catch {
            return false
        }
    }
}
ajay_nasa
  • 2,278
  • 2
  • 28
  • 45
5

Swift 4.1.

func isValidPhone(phone: String) -> Bool {

      let phoneRegex = "^[0-9]{6,14}$";
      let valid = NSPredicate(format: "SELF MATCHES %@", phoneRegex).evaluate(with: phone)
      return valid
   }

func isValidEmail(candidate: String) -> Bool {

       let emailRegex = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}"
       var valid = NSPredicate(format: "SELF MATCHES %@", emailRegex).evaluate(with: candidate)
        if valid {
            valid = !candidate.contains("..")
        }
        return valid
  }
Gurjinder Singh
  • 9,221
  • 1
  • 66
  • 58
5

Swift 4.2 and Xcode 10.1

//For mobile number validation
func isValidPhone(phone: String) -> Bool {

    let phoneRegex = "^((0091)|(\\+91)|0?)[6789]{1}\\d{9}$";
    let valid = NSPredicate(format: "SELF MATCHES %@", phoneRegex).evaluate(with: phone)
    return valid
}

//For email validation
func isValidEmail(candidate: String) -> Bool {

    let emailRegex = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}"
    var valid = NSPredicate(format: "SELF MATCHES %@", emailRegex).evaluate(with: candidate)
    if valid {
        valid = !candidate.contains("..")
    }
    return valid
}

Use like this

//Button Action
@IBAction func onClickRegrBtn(_ sender: UIButton) {
    //Check net connection here
    let networkReachability = Reachability.forInternetConnection()
    let networkStatus:Int = (networkReachability?.currentReachabilityStatus())!.rawValue
    if networkStatus == NotReachable.rawValue {
        let msg = SharedClass.sharedInstance.noNetMsg
        SharedClass.sharedInstance.alert(view: self, title: "", message: msg)//Display alert message
    } else {

        let mobileTrimmedString = mobileNoTF.text?.trimmingCharacters(in: .whitespaces) //Trim white spaces

        if mobileTrimmedString != "" {
            if isValidPhone(phone: mobileTrimmedString!) == false {
                SharedClass.sharedInstance.alert(view: self, title: "", message: "Please enter valid mobile number")
            } else {
                UserDefaults.standard.set(mobileTrimmedString, forKey: "mobile") //setObject
                sendMobileNumber()//Call function...
            }

        } else {
            mobileNoTF.text = ""
            //Call alert function
            SharedClass.sharedInstance.alert(view: self, title: "", message: "Please enter mobile number")
        }
    }
}
Naresh
  • 16,698
  • 6
  • 112
  • 113
  • Error: `error: argument type 'String' does not conform to expected type 'CVarArg' let valid = NSPredicate(format: "SELF MATCHES %@", phoneRegex).evaluate(with: phone)` – Binh Ho Mar 18 '22 at 09:02
  • 1
    @Binh Ho, try this `let valid = NSPredicate(format: "SELF MATCHES %@", phoneRegex as CVarArg).evaluate(with: phone) ` – Naresh Mar 18 '22 at 10:08
  • I didn't get any error, just not i tried, if you got any error try my above mentioned code. – Naresh Mar 18 '22 at 10:10
  • Maybe I tested on online swift tool. All Foundation methods not support on linux platform. – Binh Ho Mar 19 '22 at 03:29
3

Phone regex only for ّIran phone number

func isValidPhone(phone: String) -> Bool {

        let PHONE_REGEX = "^09[0-9'@s]{9,9}$"
        let phoneTest = NSPredicate(format: "SELF MATCHES %@", PHONE_REGEX)
        let result =  phoneTest.evaluate(with: phone)
        return result

    }
Mohammad Razipour
  • 3,643
  • 3
  • 29
  • 49
2

For Swift 3.0 and above

var isPhoneNumber: Bool{
let allowedCharacters = CharacterSet(charactersIn: "+0123456789").inverted
let inputString = components(separatedBy: allowedCharacters)
let filtered = inputString.joined(separator: "")
return self == filtered}
Hiren Panchal
  • 2,963
  • 1
  • 25
  • 21
1

Kirit Modi's response about Email Validation for Swift 3:

func isValidEmail(testStr:String) -> Bool {
    let emailRegEx = "^(?:(?:(?:(?: )*(?:(?:(?:\\t| )*\\r\\n)?(?:\\t| )+))+(?: )*)|(?: )+)?(?:(?:(?:[-A-Za-z0-9!#$%&’*+/=?^_'{|}~]+(?:\\.[-A-Za-z0-9!#$%&’*+/=?^_'{|}~]+)*)|(?:\"(?:(?:(?:(?: )*(?:(?:[!#-Z^-~]|\\[|\\])|(?:\\\\(?:\\t|[ -~]))))+(?: )*)|(?: )+)\"))(?:@)(?:(?:(?:[A-Za-z0-9](?:[-A-Za-z0-9]{0,61}[A-Za-z0-9])?)(?:\\.[A-Za-z0-9](?:[-A-Za-z0-9]{0,61}[A-Za-z0-9])?)*)|(?:\\[(?:(?:(?:(?:(?:[0-9]|(?:[1-9][0-9])|(?:1[0-9][0-9])|(?:2[0-4][0-9])|(?:25[0-5]))\\.){3}(?:[0-9]|(?:[1-9][0-9])|(?:1[0-9][0-9])|(?:2[0-4][0-9])|(?:25[0-5]))))|(?:(?:(?: )*[!-Z^-~])*(?: )*)|(?:[Vv][0-9A-Fa-f]+\\.[-A-Za-z0-9._~!$&'()*+,;=:]+))\\])))(?:(?:(?:(?: )*(?:(?:(?:\\t| )*\\r\\n)?(?:\\t| )+))+(?: )*)|(?: )+)?$"
    let emailTest = NSPredicate(format:"SELF MATCHES %@", emailRegEx)
    let result = emailTest.evaluate(with: testStr)
    return result
  }
Wilson
  • 9,006
  • 3
  • 42
  • 46
0

File-New-File.Make a Swift class named AppExtension.Add the following.

        extension UIViewController{
            func validateEmailAndGetBoolValue(candidate: String) -> Bool {
                let emailRegex = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,6}"
                return NSPredicate(format: "SELF MATCHES %@", emailRegex).evaluateWithObject(candidate)
            }
        }

        Use: 
        var emailValidator:Bool?
        self.emailValidator =  self.validateEmailAndGetBoolValue(resetEmail!)
                        print("emailValidator : "+String(self.emailValidator?.boolValue))

        Use a loop to alternate desired results.


    OR
        extension String
        {
        //Validate Email
            var isEmail: Bool {
                do {
                    let regex = try NSRegularExpression(pattern: "^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$", options: .CaseInsensitive)
                    return regex.firstMatchInString(self, options: NSMatchingOptions(rawValue: 0), range: NSMakeRange(0, self.characters.count)) != nil
                } catch {
                    return false
                }

            }
        }

        Use:
        if(resetEmail!.isEmail)
                        {
                        AppController().requestResetPassword(resetEmail!)
                        self.view.makeToast(message: "Sending OTP")
                        }
                        else
                        {
                            self.view.makeToast(message: "Please enter a valid email")
                        }
Alvin George
  • 14,148
  • 92
  • 64
0

You can create separate class for validation as below:

enum AIValidationRule: Int {
case
EmptyCheck,
MinMaxLength,
FixedLength,
EmailCheck,
UpperCase,
LowerCase,
SpecialCharacter,
DigitCheck,
WhiteSpaces,
None

}

let ValidationManager = AIValidationManager.sharedManager


func validateTextField(txtField:AITextField, forRule rule:AIValidationRule, withMinimumChar minChar:Int, andMaximumChar maxChar:Int) -> (isValid:Bool, errMessage:String, txtFieldWhichFailedValidation:AITextField)? {

    switch rule {

    case .EmptyCheck:
        return (txtField.text?.characters.count == 0) ? (false,"Please enter \(txtField.placeholder!.lowercased())",txtField) : nil


    case .MinMaxLength:
        return (txtField.text!.characters.count < minChar || txtField.text!.characters.count > maxChar) ? (false,"\(txtField.placeholder!) should be of \(minChar) to \(maxChar) characters",txtField) : nil

    case .FixedLength:
        return (txtField.text!.characters.count != minChar) ? (false,"\(txtField.placeholder!) should be of \(minChar) characters",txtField) : nil


    case .EmailCheck:
        return (!(txtField.text?.isValidEmail())!) ? (false,"Please enter valid email",txtField) : nil


    case .UpperCase:
        return ((txtField.text! as NSString).rangeOfCharacter(from: NSCharacterSet.uppercaseLetters).location == NSNotFound) ? (false,"\(txtField.placeholder!) should contain atleast one uppercase letter",txtField) : nil


    case .LowerCase:
        return ((txtField.text! as NSString).rangeOfCharacter(from: NSCharacterSet.lowercaseLetters).location == NSNotFound) ? (false,"\(txtField.placeholder!) should contain atleast one lowercase letter",txtField) : nil


    case .SpecialCharacter:
        let symbolCharacterSet = NSMutableCharacterSet.symbol()
        symbolCharacterSet.formUnion(with: NSCharacterSet.punctuationCharacters)
        return ((txtField.text! as NSString).rangeOfCharacter(from: symbolCharacterSet as CharacterSet).location == NSNotFound) ? (false,"\(txtField.placeholder!) should contain atleast one special letter",txtField) : nil


    case .DigitCheck:
        return ((txtField.text! as NSString).rangeOfCharacter(from: NSCharacterSet(charactersIn: "0123456789") as CharacterSet).location == NSNotFound) ? (false,"\(txtField.placeholder!) should contain atleast one digit letter",txtField) : nil

    case .WhiteSpaces:
        return (txtField.text!.containsAdjacentSpaces() || txtField.text!.isLastCharcterAWhiteSpace()) ? (false,"\(txtField.placeholder!) seems to be invalid",txtField) : nil

    case .None:
        return nil
    }
}

    func validateTextField(txtField:AITextField, forRules rules:[AIValidationRule]) -> (isValid:Bool, errMessage:String, txtFieldWhichFailedValidation:AITextField)? {
    return validateTextField(txtField: txtField, forRules: rules, withMinimumChar: 0, andMaximumChar: 0)
}



func validateTextField(txtField:AITextField, forRules rules:[AIValidationRule], withMinimumChar minChar:Int, andMaximumChar maxChar:Int) -> (isValid:Bool, errMessage:String, txtFieldWhichFailedValidation:AITextField)? {

    var strMessage:String = ""
    for eachRule in rules {

        if let result = validateTextField(txtField: txtField, forRule: eachRule, withMinimumChar: minChar, andMaximumChar: maxChar) {
            if(eachRule == AIValidationRule.EmptyCheck){
                return result
            }else{
                strMessage += "\(strMessage.characters.count == 0 ? "" : "\n\n") \(result.errMessage)"
            }
        }
    }
    return strMessage.characters.count > 0 ? (false,strMessage,txtField) : nil
}
Dhaval H. Nena
  • 3,992
  • 1
  • 37
  • 50
0

Using Swift 3

 func validate(value: String) -> Bool {
    let PHONE_REGEX = "^\\d{3}-\\d{3}-\\d{4}$"
    let phoneTest = NSPredicate(format: "SELF MATCHES %@", PHONE_REGEX)
    let result =  phoneTest.evaluate(with: value)
    return result
}
Saneesh
  • 1,796
  • 16
  • 23
0

Updated for Swift :

Used below code for Email, Name, Mobile and Password Validation;

// Name validation
func isValidName(_ nameString: String) -> Bool {

    var returnValue = true
    let mobileRegEx =  "[A-Za-z]{2}"  // "^[A-Z0-9a-z.-_]{5}$"

    do {
        let regex = try NSRegularExpression(pattern: mobileRegEx)
        let nsString = nameString as NSString
        let results = regex.matches(in: nameString, range: NSRange(location: 0, length: nsString.length))

        if results.count == 0
        {
            returnValue = false
        }

    } catch let error as NSError {
        print("invalid regex: \(error.localizedDescription)")
        returnValue = false
    }

    return  returnValue
}

// password validation
func isValidPassword(_ PasswordString: String) -> Bool {

    var returnValue = true
    let mobileRegEx =  "[A-Za-z0-9.-_@#$!%&*]{5,15}$"  // "^[A-Z0-9a-z.-_]{5}$"

    do {
        let regex = try NSRegularExpression(pattern: mobileRegEx)
        let nsString = PasswordString as NSString
        let results = regex.matches(in: PasswordString, range: NSRange(location: 0, length: nsString.length))

        if results.count == 0
        {
            returnValue = false
        }

    } catch let error as NSError {
        print("invalid regex: \(error.localizedDescription)")
        returnValue = false
    }

    return  returnValue
}

// email validaton
func isValidEmailAddress(_ emailAddressString: String) -> Bool {

    var returnValue = true
    let emailRegEx = "[A-Z0-9a-z.-_]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,3}"

    do {
        let regex = try NSRegularExpression(pattern: emailRegEx)
        let nsString = emailAddressString as NSString
        let results = regex.matches(in: emailAddressString, range: NSRange(location: 0, length: nsString.length))

        if results.count == 0
        {
            returnValue = false
        }

    } catch let error as NSError {
        print("invalid regex: \(error.localizedDescription)")
        returnValue = false
    }

    return  returnValue
}

// mobile no. validation
func isValidPhoneNumber(_ phoneNumberString: String) -> Bool {

    var returnValue = true
    //        let mobileRegEx = "^[789][0-9]{9,11}$"
    let mobileRegEx = "^[0-9]{10}$"

    do {
        let regex = try NSRegularExpression(pattern: mobileRegEx)
        let nsString = phoneNumberString as NSString
        let results = regex.matches(in: phoneNumberString, range: NSRange(location: 0, length: nsString.length))

        if results.count == 0
        {
            returnValue = false
        }

    } catch let error as NSError {
        print("invalid regex: \(error.localizedDescription)")
        returnValue = false
    }

    return  returnValue
}

//How to use?

let isFullNameValid = isValidName("ray")

if isFullNameValid{
    print("Valid name...")
}else{
    print("Invalid name...")
}
Kiran Jadhav
  • 3,209
  • 26
  • 29
0

"validate Email"-Solution for Swift 4: Create this class:

import Foundation

public class EmailAddressValidator {
    public init() {
    }

    public func validateEmailAddress(_ email: String) -> Bool {
        let emailTest = NSPredicate(format: "SELF MATCHES %@", String.emailValidationRegEx)

        return emailTest.evaluate(with: email)
    }
}

private extension String {
    static let emailValidationRegEx = "(?:[\\p{L}0-9!#$%\\&'*+/=?\\^_`{|}~-]+(?:\\.[\\p{L}0-9!#$%\\&'*+/=?\\^_`{|}" +
        "~-]+)*|\"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\" +
        "x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")@(?:(?:[\\p{L}0-9](?:[a-" +
        "z0-9-]*[\\p{L}0-9])?\\.)+[\\p{L}0-9](?:[\\p{L}0-9-]*[\\p{L}0-9])?|\\[(?:(?:25[0-5" +
        "]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-" +
        "9][0-9]?|[\\p{L}0-9-]*[\\p{L}0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21" +
    "-\\x5a\\x53-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)\\])"
}

and use it like this:

let validator = EmailAddressValidator()
let isValid = validator.validateEmailAddress("testmail@testmail.com")
Jochen Holzer
  • 1,598
  • 19
  • 25
-1

another solution for variety sake..

public extension String {
    public var validPhoneNumber:Bool {
        let types:NSTextCheckingType = [.PhoneNumber]
        guard let detector = try? NSDataDetector(types: types.rawValue) else { return false }

        if let match = detector.matchesInString(self, options: [], range: NSMakeRange(0, characters.count)).first?.phoneNumber {
            return match == self
        }else{
            return false
        }
    }
}

//and use like so:
if "16465551212".validPhoneNumber {
    print("valid phone number")
}
iksnae
  • 1,030
  • 11
  • 18
  • 1
    The result of validPhoneNumber will always return "true". It's just creating a NSTextCheckingResult of the phoneNumber type, so the comparison is always true. I think you meant to try using NSDataDetector. – EPage_Ed Apr 11 '16 at 23:38
  • thank you @EPage_Ed you were 100% correct! I've updated to reflect intended implementation. thanks! – iksnae Aug 03 '16 at 01:14