Check that an email address is valid on iOS

117,011

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.

Share:
117,011

Related videos on Youtube

raaz
Author by

raaz

hi, i m an iOS developer.

Updated on June 11, 2020

Comments

  • raaz
    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
      PurplePilot about 14 years
      valid email in that it is [email protected] or valid in that it is a real email that exists and will accept mail?
    • raaz
      raaz about 14 years
      I 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
      dusker about 14 years
      there'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
    Alex about 14 years
    That'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
    BadPirate almost 14 years
    Actually, you can use NSPredicate, which can handle regular expressions.
  • Victor
    Victor about 11 years
    Nice function! Worked great!
  • Warif Akhand Rishi
    Warif Akhand Rishi almost 11 years
    Worked nice until now. Today our tester found a bug [email protected] shows valid email.
  • Warif Akhand Rishi
    Warif Akhand Rishi almost 11 years
    I'm using NSString *stricterFilterString = @"^[_A-Za-z0-9-+]+(\\.[_A-Za-z0-9-+]+)*@[A-Za-z0-9-]+(\\.[A-‌​Za-z0-9-]+)*(\\.[A-Z‌​a-z]{2,4})$";
  • BadPirate
    BadPirate almost 11 years
    Thanks @WarifAkhandRishi -- I've updated the strings to handle your negative test case.
  • harshit2811
    harshit2811 over 10 years
    does 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
    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
    harshit2811 over 10 years
    Ok.. So i just have to check whether "@" and "." is available in email address when user types the email in input field?
  • Lion789
    Lion789 about 10 years
    Trying this and it keeps crashing... calling it like so [self NSStringIsValidEmail:textToCheck] --am I doing something wrong?
  • BadPirate
    BadPirate about 10 years
    Looks like you are calling it correct lion. Whats the crash?
  • Hamza Hasan
    Hamza Hasan about 10 years
    Luv you boy. Works great...
  • Juan Carlos Ospina Gonzalez
    Juan Carlos Ospina Gonzalez almost 10 years
    Or 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
    mahboudz almost 10 years
    new TLDs like .museum and .travel will not pass the strict test.
  • Berni
    Berni almost 10 years
    There 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
    BadPirate almost 10 years
    @Berni - I mention this in the discussion the website, the "Lax" String allows for addresses like .museum and .travel
  • Berni
    Berni almost 10 years
    @BadPirate OK. But the Problem is about the - (dash) in de Host: like t-online.de
  • BadPirate
    BadPirate almost 10 years
    @berni - Thanks, found the issue and fixed it.
  • sahara108
    sahara108 almost 10 years
    Thank 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
    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
    sahara108 almost 10 years
    Yes, the [email protected] should not be valid. Sorry, what do you mean lax.
  • BadPirate
    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
    sahara108 almost 10 years
    I am not good at regex :(. I just use rangeOfString:@".." to check it.
  • SURESH SANKE
    SURESH SANKE over 9 years
    Very nice function to validate email...thans a lot
  • Ilesh P
    Ilesh P over 9 years
    In swift language This link very useful for Validation email stackoverflow.com/questions/5428304/…
  • Dov
    Dov over 9 years
    This is an even better option in Swift, since rangeOfString() returns an optional, which is nil if there's no match
  • cynistersix
    cynistersix over 9 years
    Does anyone know of a regex that will work for international email addresses? (cyrillic, etc.)
  • BadPirate
    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
    samouray about 9 years
    Works like a charm , Thanks man !
  • user1904273
    user1904273 about 9 years
    Beginner 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
    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
    Mercurial about 9 years
    asdf@[email protected] passes the validation and it shouldn't ?
  • BadPirate
    BadPirate about 9 years
    Good catch @Mercurial - Made sure there aren't any trailing or leading characters.
  • Joan Cardona
    Joan Cardona almost 9 years
    this accepts aa@[email protected]
  • BadPirate
    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
    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
    Omer Waqas Khan over 8 years
    It accepts these cases, "test@@test.com" "[email protected]" "[email protected]" "@[email protected]"
  • Gajendra Rawat
    Gajendra Rawat over 8 years
    this validation is getting faild if I am entering emai laddress with space charector
  • Matthew Cawley
    Matthew Cawley over 8 years
    @morroko: email addresses should not contain a space
  • Vanilla Boy
    Vanilla Boy about 8 years
    But, still this function will accept "[email protected]" ????
  • BadPirate
    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
    Hugo about 8 years
    Please note this case "123@qq.com". This should result false. Because @ and @ is different. The code can not handle this case.
  • Ishwar Hingu
    Ishwar Hingu about 8 years
    still accept [email protected]
  • PLJNS
    PLJNS almost 8 years
    Opinionated 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
    Admin about 7 years
    What about this email address. "[email protected]" Returning valid email address
  • BadPirate
    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
    Mathi Arasan almost 7 years
    It accepts <null>@mail.com. Is that correct?
  • Admin
    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
    Deantwo over 6 years
    So you aren't allowing "root@localhost"? That is a valid e-mail address.
  • Deantwo
    Deantwo over 6 years
    While it might be for another programming language, I suggest reading this: stackoverflow.com/a/1374644/5815327
  • Anup Gupta
    Anup Gupta over 6 years
    In this Have bug Its accepting @@@@@@gmail.com