views:

4008

answers:

9

What is the cleanest way to validate an email address that a user enters that is Cocoa-Touch 2.0 compatible?

+2  A: 

I have found that using a regular expression works quite well to validate an email address.

The major downside to regular expressions of course is maintainability, so comment like you have never commented before. I promise you, if you don't you will wish you did when you go back to the expression after a few weeks.

Here is a link to a good source, http://www.regular-expressions.info/email.html.

Paul
I implemented the second-last one on that page recently, and I'm quite happy with it. It works fine for a simple [email protected] email address, with no quotes or brackets for a full name. Works great for web form validation where people won't be typing that sort of thing in anyway.
zombat
Poor people with their .museum TLD.
BadPirate
+4  A: 

Read the RFC. Almost everyone that thinks they know how to parse/clean/validate an email address is wrong.

http://tools.ietf.org/html/rfc2822 Section 3.4.1 is very useful. Notice

dtext           =       NO-WS-CTL /     ; Non white space controls

                        %d33-90 /       ; The rest of the US-ASCII
                        %d94-126        ;  characters not including "[",
                                        ;  "]", or "\"

Yes, that means +, ', etc are all legit.

Trey
+2  A: 

Attempt to send an email to the address and see if anyone replies to it.

apphacker
+3  A: 

A good start is to decide what do you and do you not want to accept as an email address?

99% of of email addresses look like this: [email protected] or [email protected]

However, it's technically legal to have an email address like this: f!#$%&'*+-/=?^_{|}~"ha!"@com

There are probably only a handful of valid emails in the world for top-level domains, and almost nobody uses most of those other characters (especially quotes and backticks), so you might want to assume that these are all invalid things to do. But you should do so as a conscious decision.

Beyond that, do what Paul says and try to match the input to a regular expression like this: ^[A-Z0-9._%+-]+@[A-Z0-9.-]+.[A-Z]{2,4}$

That one will match pretty much everybody's email address.

CaptainAwesomePants
+3  A: 

While the focus on regular expressions is good, but this is only a first and necessary step. There are other steps that also need to be accounted for a good validation strategy.

Two things on top of my head are :

  1. DNS validation to make sure the domain actually exists.

  2. After dns validation, you can also choose to do an smtp validation. send a call to the smtp server to see if the user actually exists.

In this way you can catch all kinds of user errors and make sure it is a valid email.

CodeToGlory
+6  A: 

The best solution I have found so far (and the one I ended up going with) is to add RegexKitLite To the project which gives access to regular expressions via NSString Categories.

It is quite painless to add to the project and once in place, any of the regular expression email validation logic will work.

Marcus S. Zarra
NSPredicate can do RegEx without adding additional libraries to your project.
BadPirate
This question, from April of 2009 was before NSPredicate existed on iOS.
Marcus S. Zarra
+25  A: 

I like the one from DHValidation:

- (BOOL) validateEmail: (NSString *) candidate {
    NSString *emailRegex = @"[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}"; 
    NSPredicate *emailTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", emailRegex]; 

    return [emailTest evaluateWithObject:candidate];
}
catlan
Great but doesn't work on OS <3.0, because NSPredicate is not available.
Felixyz
Nice. Everyone forgets that NSPredicate can run regexps.
Roger Nolan
That is one very bad regexp. For instance, it will fail on people using the .museum top domain. Refer to this article: http://www.linuxjournal.com/article/9585
Jonny
So apart from changing the end to {2,6}, what changes could be made to significantly improve this regex to make it work for most common cases?
TomA
There's a more complete regex at http://cocoawithlove.com/2009/06/verifying-that-string-is-email-address.html that can be used instead of this simple one.
TomA
A: 

Good cocoa function:

BOOL NSStringIsValidEmail(NSString *checkString)
{
 BOOL sticterFilter = YES; // Discussion http://blog.logichigh.com/2010/09/02/validating-an-e-mail-address/

 NString *stricterFilterString = @"[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}";
 NSString *laxString = @".+@.+\.[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/

BadPirate
This question is focused on being iOS 2.0 compatible. `NSPredicate` did not exist in 2.0.
Marcus S. Zarra