Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I've been modifying some code to work between Mac OS X and iPhone OS.

I came across some code that was using NSURL's URLByAppendingPathComponent: (added in 10.6), which as some may know, isn't available in the iPhone SDK.

My solution to make this code work between OS's is to use

NSString *urlString = [myURL absoluteString]; urlString = [urlString stringByAppendingPathComponent:@"helloworld"]; myURL = [NSURL urlWithString:urlString]; 

The problem with this is that NSString's stringByAppendingPathComponent: seems to remove one of the /'s from the http:// part of the URL.

Is this intended behaviour or a bug?


Edit

Ok, So I was a bit too quick in asking the question above. I re-read the documentation and it does say:

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

However, it doesn't give any pointers in the right direction for what to do if you need to append a path component to a URL on the iPhone...

I could always just do it manually, adding a /if necessary and the extra string, but I was looking to keep it as close to the original Mac OS X code as possible...

like image 768
Jasarien Avatar asked Apr 05 '10 16:04

Jasarien


2 Answers

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.

like image 90
Chuck Avatar answered Sep 24 '22 16:09

Chuck


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.

like image 20
nschum Avatar answered Sep 25 '22 16:09

nschum