Data Detection for Links

If you need to determine if a text string contains a valid URL link resist the temptation to start constructing a regular expression and take a look at the NSDataDetector class from the Foundation framework.

NSDataDetector

The NSDataDetector Class Reference was introduced to the Foundation framework with iOS 4.0 so has been around for a while. It is defined in NSRegularExpression.h which also has this useful explanation:

NSDataDetector is a specialized subclass of NSRegularExpression. Instead of finding matches to regular expression patterns, it matches items identified by Data Detectors, such as dates, addresses, and URLs.

There is a single class method to initialise a new data detector named +dataDetectorWithTypes:error: where you must specify one or more data detector types to check. As time of writing (iOS 7.1) the possible options are:

You can OR these values if you want to check for more than one type. However in this case if I just want to check for links I would initialise a data detector as follows:

NSError *error = nil;
NSDataDetector *detector = [NSDataDetector dataDetectorWithTypes:NSTextCheckingTypeLink 
                                                           error:&error];

Once the data detector is created there are several useful NSRegularExpression methods to check an NSString depending on the desired result:

Counting matches

To simply determine if an NSString contains one or more links use numberOfMatchesInString:options:range:

NSString *stringValue = @"A link: http://useyourloaf.com";
NSUInteger matchCount = [detector numberOfMatchesInString:stringValue
                                                  options:0 
                                                    range:NSMakeRange(0, stringValue.length)];

Finding first match

To find the first link in the string and extract the URL value use firstMatchInString:options:range:. This method returns an NSTextCheckingResult object which if successful will contain an NSURL object for the detected link:

NSString *stringValue =  @"Two links: useyourloaf.com and apple.com"; 
NSURL *url = nil;
NSTextCheckingResult *result = [detector firstMatchInString:stringValue
                                                    options:0
                                                      range:NSMakeRange(0, stringValue.length)];
if (result.resultType == NSTextCheckingTypeLink)
{
    url = result.URL;
}
NSLog(@"matched: %@", url);
// matched: http://useyourloaf.com

Note that the resultType value returned in the NSTextCheckingResult indicates the matching data detector type. In this case the data detector is only matching links so it should always contain NSTextCheckingTypeLink and will have an NSURL object. If you are checking for multiple types you should check which one actually matched as the additional information will vary (for example for NSTextCheckingTypePhoneNumber use the phoneNumber property).

Finding all matches

If you want to find all links in the string you can use matchesInString:options:range: and get back an NSArray of NSTextCheckingResult objects (one for each link matched). Alternatively you can use a block method to enumerate all matches:

NSString *stringValue = @"Two links: useyourloaf.com and apple.com";    
[detector enumerateMatchesInString:stringValue
                           options:0
                             range:NSMakeRange(0, stringValue.length)
                        usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop)
{
    if (result.resultType == NSTextCheckingTypeLink)
    {
        NSLog(@"matched: %@",result.URL);
    }         
}];
// matched: http://useyourloaf.com
// matched: http://apple.com

Never miss a post!

iOS Size Classes Cheat Sheet

Subscribe and get my free iOS Size Classes Cheat Sheet

Success! Now check your email to confirm your subscription and download your free guide to iOS Size Classes.

There was an error submitting your subscription. Please try again.

Unsubscribe at any time.
No time to watch WWDC videos?

Sign up to get my iOS posts direct to your inbox and I will send you a free PDF of my iOS Size Classes Cheat Sheet.

OK! Check your inbox (or spam folder) for an email to confirm your details and download your free guide to iOS Size Classes.

There was an error submitting your subscription. Please try again.

Unsubscribe at any time.
Archives Categories