Automatic Link Detection in an NSTextView

NSTextView is a really powerful text view class. It can do all kinds of stuff like automatic spelling correction, email, phone number, and address detection, and link detection. I was working on a chat application and I wanted to have links that people sent be clickable. I was using an NSTextView because it has the automaticLinkDetection property.

Unfortunately, I couldn’t get links to show up in my app. I tried sending it delegate messages and lots of other stuff. It just wouldn’t work when I set the text programatically. It would only work when I was actually typing in to the NSTextView and even then, it was a little flaky. I posted a question on StackOverflow and didn’t get any answers.

So to fix the problem, I did the link detection myself. I look through the text view for links and then add them myself as NSAttributedStrings. I did this using three different categories.

There is NSAttributedString+Hyperlink, NSString+FindURLs, and NSTextView+AutomaticLinkDetection. I use the FindURLs category to find the links and their locations, then I use the Hyperlink category to format the string like a link, and the AutomaticLinkDetection category to bring them together.

You use it like this

[myTextView setString:@"http://google.com http://apple.com"];

[myTextView detectAndAddLinks];

And here is the implementation

-(void)detectAndAddLinks

{

NSArray *linkLocations = [[self string] locationsOfLinks];

NSArray *links = [[self string] arrayOfLinks];

int i=0;

for( NSString *link in links )

{

NSAttributedString *linkString = [NSAttributedString hyperlinkFromString:link withURL:[NSURL URLWithString:link]];

[[self textStorage] replaceCharactersInRange:[[linkLocations objectAtIndex:i] range] withAttributedString:linkString];

i++;

}

}

I put an example project on GitHub that you can look at and use.

Let me know if there was something I missed that would make it so I don’t have to use the category.

  1. Stefan:

    You may also want to have a look at my AutoHyperlinks.framework. It’s a forked lightweight variant of what Adium uses, Intel 64-bit, ARC powered and Mac App Store conform. Anyway, thanks for sharing this code, it seems pretty elegant and easy to implement, maybe I can use this for a completely rewritten variant of AutoHyperlinks some day ;)

    https://github.com/ByteProject/AutoHyperlinks.framework

  2. Seth:

    [textView checkTextInDocument:nil];

  3. Rob:

    @Seth

    Thanks, [textView checkTextInDocument:nil] works perfectly!

  4. John Wright:

    Thanks so much, this works great!

  5. Pushpendra singh:

    Do apple support it….?/