Find URL in string

November 30, 2015

Find URL in string

There are times, when we need to parse some string and extract any URLs we find there. Sounds like a simple task, but becomes quite an interesting task to accomplish. Thankfully we have our hero from the Foundation - NSDataDetector.

Usage

NSDataDetector is a subclass of NSRegularExpression, but here we don't have to play with regular expression here. In this class we have already defined typed of data that is going to be searched in the strings. In this example I will be using NSTextCheckingTypeLink just because we are looking for URLs, but you could also with this class look for addresses, dates, quotes, phone numbers etc.

NSString *sample = @"This is some sample string, that leads to http://arsenkin.com";
NSDataDetector *detector = [NSDataDetector dataDetectorWithTypes:NSTextCheckingTypeLink error:nil];
NSArray *matches = [detector matchesInString:sample options:0 range:NSMakeRange(0, sample.length)];
/* Array contains one url http://arsenkin.com */

This block of code had searched the whole string for URLs it could find. It would also find URLs like arsenkin.com, without the 'http://' part, so this class is a great helper.

In case you would print out the contents of the matches array, you would see, that it holds instances of the NSTextCheckingResult class.

NSLog(@"%@", matches);
/* NSDataSetector[21738:3045506] (
    "<NSLinkCheckingResult: 0x100111030>{42, 19}{http://arsenkin.com}"
) */

Getting the actual NSURL

Here is how you would actually create NSURL instance from those NSTextCheckingResult instances you have in your array:

for (NSTextCheckingResult *match in matches) {
    NSRange matchRange = [match range];
    if ([match resultType] == NSTextCheckingTypeLink) {
        NSURL *url = [match URL];
    }
}

Here we are simply checking for the type of NSTextCheckingResult, since there are different types of data you might be looking for, like phone numbers or addresses.

More methods

There are more ways you could work with NSDataDetector. For example, you could get a number of links the class was able to find with method - numberOfMatchesInString:options:range:. Or you could enumerate through them with - enumerateMatchesInString:options:range:usingBlock:. Or even get the first encountered URL with - firstMatchInString:options:range:.

The class itself has pretty much what you need for basic day-to-day stuff to get done. I really like using it when I have to quickly get URLs from string and I don't want to create a freaking regular expression line of gibberish.

Comments

comments powered by Disqus