[Solved] What are some different ways of making an effective email validation method without using regular expression in objective c?


my attempt

@interface Tester : NSObject
+(BOOL) testForValidMail:(NSString *)mail;
@end

@implementation Tester

+(BOOL)testForValidMail:(NSString *)string
{

    NSRange atRange = [string rangeOfString:@"@"];

    BOOL b = NO;

    if ((atRange.location != NSNotFound) //is `@` present
        && (atRange.location != 0) // and is `@` not at the beginning -> left substring exist
        && (atRange.location != string.length-1) // and not at the end -> right substring exists
        && ([[string componentsSeparatedByString:@"@"] count] == 2)) // and is there only one `@`?
    {
        // is there a `.` right of the `@`?
        NSRange dotRange = [[string substringFromIndex:atRange.length +atRange.location] rangeOfString:@"."];

        if((dotRange.location != NSNotFound) // is there a `.` right of `@`
           && (dotRange.location !=0) // and is it not the very next char after `@`
           && ([[string substringFromIndex:[string length]-2] rangeOfString:@"."].location == NSNotFound)) // and the `.` is not the last or second last char
        {
            b = YES;
        }
    }
    return b;
}

@end


int main(int argc, const char * argv[])
{

    @autoreleasepool {
    NSArray *candidates = @[@"m@m.de",
                            @"m@.de",
                            @"m@m.e",
                            @"@m.de",
                            @"m<at>m.de",
                            @"mm@mm@mm.de",
                            @"email@email.email.email.com" //if you are the owner of email.com, you can decide to create this address
                            ];
    [candidates enumerateObjectsUsingBlock:^(NSString *mailAdress, NSUInteger idx, BOOL *stop) {
            NSLog(@"%@, %@",([Tester testForValidMail:mailAdress]) ? @"YES" : @"NO", mailAdress );
        }];
    }
    return 0;
}

result:

2014-02-14 21:05:49.404 emailcheck[16271:303] YES, m@m.de
2014-02-14 21:05:49.405 emailcheck[16271:303] NO, m@.de
2014-02-14 21:05:49.406 emailcheck[16271:303] NO, m@m.e
2014-02-14 21:05:49.406 emailcheck[16271:303] NO, @m.de
2014-02-14 21:05:49.406 emailcheck[16271:303] NO, m<at>m.de
2014-02-14 21:05:49.407 emailcheck[16271:303] NO, mm@mm@mm.de
2014-02-14 21:05:49.407 emailcheck[16271:303] YES, email@email.email.email.com

I added another check: not more than one @


I rewrote my code as Category on NSString

@interface NSString (EmailAddressTest)
-(BOOL) isValidMailAddress;
@end

@implementation NSString (EmailAddressTest)

-(BOOL)isValidMailAddress
{
     NSRange atRange = [self rangeOfString:@"@"];

    BOOL b = NO;

    if ((atRange.location != NSNotFound) //is `@` present
        && (atRange.location != 0) // and is `@` not at the beginning -> left substring exist
        && (atRange.location != [self length]-1) // and not at the end -> right substring exists
        && ([[self componentsSeparatedByString:@"@"] count] == 2)) // and is there only one `@`?
    {
        // is there a `.` right of the `@`?
        NSRange dotRange = [[self substringFromIndex:atRange.length +atRange.location] rangeOfString:@"."];

        if((dotRange.location != NSNotFound) // is there a `.` right of `@`
           && (dotRange.location !=0) // and is it not the very next char after `@`
           && ([[self substringFromIndex:[self length]-2] rangeOfString:@"."].location == NSNotFound)) // and the `.` is not the last or second last char
        {
            b = YES;
        }
    }
    return b;
}

@end


int main(int argc, const char * argv[])
{

    @autoreleasepool {
        [@[@"m@m.de", @"m@.de", @"m@m.e", @"@m.de", @"m<at>m.de", @"mm@mm@mm.de"] enumerateObjectsUsingBlock:^(NSString *mailAdress, NSUInteger idx, BOOL *stop) {
            NSLog(@"%@, %@",([mailAdress isValidMailAddress]) ? @"YES" : @"NO", mailAdress );
        }];
    }
    return 0;
}

solved What are some different ways of making an effective email validation method without using regular expression in objective c?