We are a Billion Fragments (or "Removing URL Fragments with NSURL")

NSURL is a wonderfully powerful Cocoa object, bet there is at least one thing it leaves out, but I'll show you how to fix that.  URLs are composed of several distinct parts. Given the example URL of http://www.example.com:80/path/to/file/page.htm?key=val#foo this is broken into these parts:

  • scheme (http://)
  • authority (www.example.com:80)
  • path (/path/to/file/page.htm)
  • query (key=val)
  • fragment (foo)
You can read more about all of this in RFC3986.  Today I'm just focusing on the fragment part.

Frequently, you have an NSURL object and may just want the URL without the fragment, to find distinct pages in a site for example.

This Objective-C category on the NSURL object does just that.

header:

//
//  PDNSURLExtras.h
//
//  Created by Eric Vitiello on 11/5/09.
//  Copyright 2009 Eric Vitiello. All rights reserved.
//

#import 

@interface NSURL (PDExtras)
- (NSURL *)urlByRemovingFragment;
@end

implementation:

//
//  PDNSURLExtras.m
//
//  Created by Eric Vitiello on 11/5/09.
//  Copyright 2009 Eric Vitiello. All rights reserved.
//

#import "PDNSURLExtras.h"

@implementation NSURL (PDExtras)

-(NSURL *)urlByRemovingFragment {
    NSString *urlString = [self absoluteString];
    // Find that last component in the string from the end to make sure to get the last one
    NSRange fragmentRange = [urlString rangeOfString:@"#" options:NSBackwardsSearch];
    if (fragmentRange.location != NSNotFound) {
        // Chop the fragment.
        NSString* newURLString = [urlString substringToIndex:fragmentRange.location];
        return [NSURL URLWithString:newURLString];
    } else {
        return self;
    }
}

@end

To use:

NSURL *url = [NSURL URLWithString:@"http://www.example.com:80/path/to/file/page.htm?key=val#foo"];
NSURL *urlWithoutFragment = [url urlByRemovingFragment];

Nice and simple. Enjoy!