Check that an email address is valid on iOS
Solution 1
Good cocoa function:
-(BOOL) NSStringIsValidEmail:(NSString *)checkString
{
BOOL stricterFilter = NO; // Discussion http://blog.logichigh.com/2010/09/02/validating-an-e-mail-address/
NSString *stricterFilterString = @"^[A-Z0-9a-z\\._%+-]+@([A-Za-z0-9-]+\\.)+[A-Za-z]{2,4}$";
NSString *laxString = @"^.+@([A-Za-z0-9-]+\\.)+[A-Za-z]{2}[A-Za-z]*$";
NSString *emailRegex = stricterFilter ? stricterFilterString : laxString;
NSPredicate *emailTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", emailRegex];
return [emailTest evaluateWithObject:checkString];
}
Discussion on Lax vs. Strict - http://blog.logichigh.com/2010/09/02/validating-an-e-mail-address/
And because categories are just better, you could also add an interface:
@interface NSString (emailValidation)
- (BOOL)isValidEmail;
@end
Implement
@implementation NSString (emailValidation)
-(BOOL)isValidEmail
{
BOOL stricterFilter = NO; // Discussion http://blog.logichigh.com/2010/09/02/validating-an-e-mail-address/
NSString *stricterFilterString = @"^[A-Z0-9a-z\\._%+-]+@([A-Za-z0-9-]+\\.)+[A-Za-z]{2,4}$";
NSString *laxString = @"^.+@([A-Za-z0-9-]+\\.)+[A-Za-z]{2}[A-Za-z]*$";
NSString *emailRegex = stricterFilter ? stricterFilterString : laxString;
NSPredicate *emailTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", emailRegex];
return [emailTest evaluateWithObject:self];
}
@end
And then utilize:
if([@"[email protected]" isValidEmail]) { /* True */ }
if([@"InvalidEmail@notreallyemailbecausenosuffix" isValidEmail]) { /* False */ }
Solution 2
To check if a string variable contains a valid email address, the easiest way is to test it against a regular expression. There is a good discussion of various regex's and their trade-offs at regular-expressions.info.
Here is a relatively simple one that leans on the side of allowing some invalid addresses through: ^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,6}$
How you can use regular expressions depends on the version of iOS you are using.
iOS 4.x and Later
You can use NSRegularExpression
, which allows you to compile and test against a regular expression directly.
iOS 3.x
Does not include the NSRegularExpression
class, but does include NSPredicate
, which can match against regular expressions.
NSString *emailRegex = ...;
NSPredicate *emailTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", emailRegex];
BOOL isValid = [emailTest evaluateWithObject:checkString];
Read a full article about this approach at cocoawithlove.com.
iOS 2.x
Does not include any regular expression matching in the Cocoa libraries. However, you can easily include RegexKit Lite in your project, which gives you access to the C-level regex APIs included on iOS 2.0.
Solution 3
Heres a good one with NSRegularExpression that's working for me.
[text rangeOfString:@"^.+@.+\\..{2,}$" options:NSRegularExpressionSearch].location != NSNotFound;
You can insert whatever regex you want but I like being able to do it in one line.
Solution 4
to validate the email string you will need to write a regular expression to check it is in the correct form. there are plenty out on the web but be carefull as some can exclude what are actually legal addresses.
essentially it will look something like this
^((?>[a-zA-Z\d!#$%&'*+\-/=?^_`{|}~]+\x20*|"((?=[\x01-\x7f])[^"\\]|\\[\x01-\x7f])*"\x20*)*(?<angle><))?((?!\.)(?>\.?[a-zA-Z\d!#$%&'*+\-/=?^_`{|}~]+)+|"((?=[\x01-\x7f])[^"\\]|\\[\x01-\x7f])*")@(((?!-)[a-zA-Z\d\-]+(?<!-)\.)+[a-zA-Z]{2,}|\[(((?(?<!\[)\.)(25[0-5]|2[0-4]\d|[01]?\d?\d)){4}|[a-zA-Z\d\-]*[a-zA-Z\d]:((?=[\x01-\x7f])[^\\\[\]]|\\[\x01-\x7f])+)\])(?(angle)>)$
Actually checking if the email exists and doesn't bounce would mean sending an email and seeing what the result was. i.e. it bounced or it didn't. However it might not bounce for several hours or not at all and still not be a "real" email address. There are a number of services out there which purport to do this for you and would probably be paid for by you and quite frankly why bother to see if it is real?
It is good to check the user has not misspelt their email else they could enter it incorrectly, not realise it and then get hacked of with you for not replying. However if someone wants to add a bum email address there would be nothing to stop them creating it on hotmail or yahoo (or many other places) to gain the same end.
So do the regular expression and validate the structure but forget about validating against a service.
Related videos on Youtube
Comments
-
raaz about 4 years
Possible Duplicate:
Best practices for validating email address in Objective-C on iOS 2.0?I am developing an iPhone application where I need the user to give his email address at login.
What is the best way to check if an email address is a valid email address?
-
PurplePilot about 14 yearsvalid email in that it is [email protected] or valid in that it is a real email that exists and will accept mail?
-
raaz about 14 yearsI want both, if [email protected] is valid or not or wheather user give any invalid id(e.g. abc.com) Also i want to check [email protected] is a real email that will accept mail.
-
dusker about 14 yearsthere's no way to check the second condition. To check if a string is a valid email just scan it to see if '@' and . is there
-
-
Alex about 14 yearsThat's one hell of a regular expression. To use it, you'll either need to target iOS 4.0 which has the NSRegularExpression class, or use one of the many regex static libraries compiled for previous versions of iOS.
-
BadPirate almost 14 yearsActually, you can use NSPredicate, which can handle regular expressions.
-
Victor about 11 yearsNice function! Worked great!
-
Warif Akhand Rishi almost 11 yearsWorked nice until now. Today our tester found a bug
[email protected]
shows valid email. -
Warif Akhand Rishi almost 11 yearsI'm using
NSString *stricterFilterString = @"^[_A-Za-z0-9-+]+(\\.[_A-Za-z0-9-+]+)*@[A-Za-z0-9-]+(\\.[A-Za-z0-9-]+)*(\\.[A-Za-z]{2,4})$";
-
BadPirate almost 11 yearsThanks @WarifAkhandRishi -- I've updated the strings to handle your negative test case.
-
harshit2811 over 10 yearsdoes this emailregex allow spanish or so to speak non-english characters. My app is supporting more than 3 languages so i need regex which works on all language.something works on unicode.
-
BadPirate over 10 years@harshit2811 - From the discussion link - ??@??web.jp – International characters in domains and user names are already being normalized to ascii friendly code by browsers and e-mail clients, so they are being used regularly, however if you are checking before that normalization occurs, these sorts of e-mail addresses will get tossed
-
harshit2811 over 10 yearsOk.. So i just have to check whether "@" and "." is available in email address when user types the email in input field?
-
Lion789 about 10 yearsTrying this and it keeps crashing... calling it like so [self NSStringIsValidEmail:textToCheck] --am I doing something wrong?
-
BadPirate about 10 yearsLooks like you are calling it correct lion. Whats the crash?
-
Hamza Hasan about 10 yearsLuv you boy. Works great...
-
Juan Carlos Ospina Gonzalez almost 10 yearsOr in swift ;)
func isValidEmail(checkString:NSString, strictFilter strict:Bool)->Bool{ var stricterFilterString = "[A-Z0-9a-z\\._%+-]+@([A-Za-z0-9-]+\\.)+[A-Za-z]{2,4}"; var laxString = ".+@([A-Za-z0-9]+\\.)+[A-Za-z]{2}[A-Za-z]*"; var emailRegex = strict ? stricterFilterString : laxString; var emailTest:NSPredicate = NSPredicate(format:"SELF MATCHES %@", emailRegex); return emailTest.evaluateWithObject(checkString); }
-
mahboudz almost 10 yearsnew TLDs like .museum and .travel will not pass the strict test.
-
Berni almost 10 yearsThere is an error in the laxString: It does not accept: @t-online.de adresses. It should be: NSString laxString = @".+@([A-Za-z0-9]+\\.)+[A-Za-z]{2}[A-Za-z]"; sth like: SString laxString = @".+@([A-Za-z0-9.-]+\\.)+[A-Za-z]{2}[A-Za-z]";
-
BadPirate almost 10 years@Berni - I mention this in the discussion the website, the "Lax" String allows for addresses like .museum and .travel
-
Berni almost 10 years@BadPirate OK. But the Problem is about the - (dash) in de Host: like t-online.de
-
BadPirate almost 10 years@berni - Thanks, found the issue and fixed it.
-
sahara108 almost 10 yearsThank you. But the laxString return an error with the email: [email protected]. This email shouldn't be accepted as described in en.wikipedia.org/wiki/Email_address#Local_part
-
BadPirate almost 10 years@sahara108 - Are you saying that the lax string returns [email protected] as valid, even though it isn't? We are being lax :)
-
sahara108 almost 10 yearsYes, the [email protected] should not be valid. Sorry, what do you mean lax.
-
BadPirate almost 10 years@sahara108 I wrote the Lax statement to capture most valid emails and get email that is the general shape of an email. tricks like eliminating two periods in a row are a little fancy :) Have you got an alternative regular expression to suggest?
-
sahara108 almost 10 yearsI am not good at regex :(. I just use
rangeOfString:@".."
to check it. -
SURESH SANKE over 9 yearsVery nice function to validate email...thans a lot
-
Ilesh P over 9 yearsIn
swift language
This link very useful for Validation email stackoverflow.com/questions/5428304/… -
Dov over 9 yearsThis is an even better option in Swift, since
rangeOfString()
returns an optional, which isnil
if there's no match -
cynistersix over 9 yearsDoes anyone know of a regex that will work for international email addresses? (cyrillic, etc.)
-
BadPirate over 9 years@cynistersix - Non-ASCII isn't officially supported by all mail servers / clients yet. Ideally if you spot non-ASCII characters, you would encode it to a supported alias (ie.. Punycode) stackoverflow.com/a/760318/285694 - And verify the result.
-
samouray about 9 yearsWorks like a charm , Thanks man !
-
user1904273 about 9 yearsBeginner question but what constitutes passing if you just say [self NSStringIsValidEmail:textToCheck] what is it supposed to return and what is best way to call it. when I try: if ([self NSString..]) {} it does not work.
-
BadPirate about 9 years@user1904273 - If you put that method into a class call with [self NSStringIsValidEmail:@"[email protected]"] -- It will return true if the passed string is a valid email (false otherwise) and should work in the case you put above (assuming textToCheck in your case is in fact a valid email.
-
Mercurial about 9 yearsasdf@[email protected] passes the validation and it shouldn't ?
-
BadPirate about 9 yearsGood catch @Mercurial - Made sure there aren't any trailing or leading characters.
-
Joan Cardona almost 9 yearsthis accepts aa@[email protected]
-
BadPirate almost 9 years@JoanCardona - The addition of ^ and $ into the regular expression should have fixed this (and appears to in my tests)
-
Rick van der Linde over 8 years+5 years old and still rocking! I've combined strict and lax with NSCompoundPredicate orPredicateWithSubpredicates and it's working great, thnx.
-
Omer Waqas Khan over 8 yearsIt accepts these cases, "test@@test.com" "[email protected]" "[email protected]" "@[email protected]"
-
Gajendra Rawat over 8 yearsthis validation is getting faild if I am entering emai laddress with space charector
-
Matthew Cawley over 8 years@morroko: email addresses should not contain a space
-
Vanilla Boy about 8 yearsBut, still this function will accept "[email protected]" ????
-
BadPirate about 8 years@VanillaBoy what's wrong with that address? Looks valid to me. Note, function is far too simple to do domain validation as well. Valid top level domain list is constantly expanding, so only way to do that would be some sort of network or DNS validation.
-
Hugo about 8 yearsPlease note this case "123@qq.com". This should result false. Because @ and @ is different. The code can not handle this case.
-
Ishwar Hingu about 8 yearsstill accept [email protected]
-
PLJNS almost 8 yearsOpinionated but concise Swift 3: ` extension String { func isValidEmail()->Bool{ return NSPredicate(format:"SELF MATCHES %@", ".+@([A-Za-z0-9]+\\.)+[A-Za-z]{2}[A-Za-z]*").evaluate(with: self); } }`
-
Admin about 7 yearsWhat about this email address. "[email protected]" Returning valid email address
-
BadPirate about 7 years@HPM -- Yeah, looks like the RFC allows single periods but not multiple in a row in the local portion of the email address. -- This would probably make for a pretty challenging regular expression :) If you've got one that covers all the same but gets the double period case then feel free to suggest.
-
Mathi Arasan almost 7 yearsIt accepts
<null>@mail.com
. Is that correct? -
Admin almost 7 years@BadPirate. Check with this @"[A-Z0-9a-z]+([._%+-]{1}[A-Z0-9a-z]+)*@[A-Za-z0-9-]+.{0,1}[A-Za-z]{2,}"
-
Deantwo over 6 yearsSo you aren't allowing "root@localhost"? That is a valid e-mail address.
-
Deantwo over 6 yearsWhile it might be for another programming language, I suggest reading this: stackoverflow.com/a/1374644/5815327
-
Anup Gupta over 6 yearsIn this Have bug Its accepting @@@@@@gmail.com