I'm trying to implement an iOS app, which uses RestKit. In all examples I've seen so far the following code is used to create the URLs:
NSURL *baseURL = [NSURL URLWithString:@"https://api.service.com/v1"];
NSURL *relativeURL = [NSURL URLWithString:@"/files/search" relativeToURL:baseURL];
But then [relativeURL absoluteString]
will return https://api.service.com/files/search
.
So I tried a few examples:
NSURL *baseURL1 = [NSURL URLWithString:@"https://api.service.com/v1/"];
NSURL *baseURL2 = [NSURL URLWithString:@"https://api.service.com/v1"];
NSURL *baseURL3 = [NSURL URLWithString:@"/v1" relativeToURL:[NSURL URLWithString:@"https://api.service.com"]];
NSURL *relativeURL1 = [NSURL URLWithString:@"/files/search" relativeToURL:baseURL1];
NSURL *relativeURL2 = [NSURL URLWithString:@"/files/search" relativeToURL:baseURL2];
NSURL *relativeURL3 = [NSURL URLWithString:@"/files/search" relativeToURL:baseURL3];
NSURL *relativeURL4 = [NSURL URLWithString:@"files/search" relativeToURL:baseURL1];
NSURL *relativeURL5 = [NSURL URLWithString:@"files/search" relativeToURL:baseURL2];
NSURL *relativeURL6 = [NSURL URLWithString:@"files/search" relativeToURL:baseURL3];
NSLog(@"1: %@", [relativeURL1 absoluteString]);
NSLog(@"2: %@", [relativeURL2 absoluteString]);
NSLog(@"3: %@", [relativeURL3 absoluteString]);
NSLog(@"4: %@", [relativeURL4 absoluteString]);
NSLog(@"5: %@", [relativeURL5 absoluteString]);
NSLog(@"6: %@", [relativeURL6 absoluteString]);
And this is the output:
1: https://api.service.com/files/search
2: https://api.service.com/files/search
3: https://api.service.com/files/search
4: https://api.service.com/v1/files/search
5: https://api.service.com/files/search
6: https://api.service.com/files/search
So the only example returning what I want is #4. Can anyone explain why?
I read [RFC1808] which defines the normative algorithm for resolving relative URLs
2 issues:
the relative url may not start with a / or it is considered to be absolute:
when the base url ends with a non-slash. everything from the last slash on is skipped
so that explains it. the baseURL needs to end in a / and the relative url shouldn't start with a /
You have two problems here:
Firstly, the string
/files/search
is an absolute path since it starts with a slash. Resolving it against any existing URL will ignore the existing path.Secondly,
https://api.service.com/v1
does not have a trailing slash to indicate it's a directory. Any strings resolved against it will always ignore thev1
portion.To conclude, you need that combo of a relative path —
files/search
— and directory base URL —https://api.service.com/v1/
.Another example:
` The 'http://' is necessary to use this method.