NSString's stringByAppendingPathComponent: removes a '/' in http://

I would implement a myURLByAppendingPathComponent: method on NSURL that does the same thing. The reason to give it a different name is so it doesn't override the Apple-provided method when Apple gets around to porting the 10.6 API to the iPhone (so the "my" is just an example — the point is that it's unlikely somebody else would write a method with that name).

It seems to me you just want to mess with the path rather than the whole URL. Here's an untested example:

- (NSURL *)myURLByAppendingPathComponent:(NSString *)component {
    NSString *newPath = [[self path] stringByAppendingPathComponent:component];
    return [[[NSURL alloc] initWithScheme: [self scheme] 
                                     host: [self host] 
                                     path: newPath]
                                     autorelease];
}

It would only work correctly with URLs that have file-like paths, but I'm pretty sure the Apple method works the same way. At any rate, hopefully it helps you in the right direction.


URLByAppendingPathComponent

Since iOS 4, URLByAppendingPathComponent is available on iOS and handles the two slashes correctly. (OS X had it since 10.6., as Chuck points out)

myURL = [myURL URLByAppendingPathComponent:@"hello world"]
// http://foo/bar/hello%20world

Note that unlike stringByAppendingPathComponent, this method escapes the argument.

URLWithString:relativeToURL:

Alternatively, there is URLWithString:relativeToURL:, which does not escape. So if the url component is already escaped, use:

myURL = [NSURL URLWithString:@"hello%20world" relativeToURL:myURL]
// http://foo/bar/hello%20world

Note that myURL needs to end with a slash here and the added segment must not have a leading slash.


The NSString Reference says this about stringByAppendingPathComponent:

Note that this method only works with file paths (not, for example, string representations of URLs).

So, I think it's a case of "Don't Do That".

Use -stringByAppendingString: instead?