NSURL URLWithString: relativeToURL: está recortando la URL relativa

Estoy intentando implementar una aplicación de iOS, que usa RestKit. En todos los ejemplos que he visto hasta ahora, el siguiente código se usa para crear las URL:

NSURL *baseURL = [NSURL URLWithString:@"https://api.service.com/v1"]; NSURL *relativeURL = [NSURL URLWithString:@"/files/search" relativeToURL:baseURL]; 

Pero luego [relativeURL absoluteString] devolverá https://api.service.com/files/search .

Entonces probé algunos ejemplos:

 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]); 

Y esta es la salida:

 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 

Entonces, el único ejemplo que devuelve lo que quiero es # 4. ¿Alguien puede explicar por qué?

Leí [RFC1808] que define el algorithm normativo para la resolución de URL relativas

2 numbers:

  1. la url relativa puede no comenzar con a / o se considera absoluta:

     Step 4: If the embedded URL path is preceded by a slash "/", the path is not relative and we skip to Step 7." 
  2. cuando la url de la base termina con una barra no inclinada. se omite todo desde la última barra en

     Step 6: The last segment of the base URL's path (anything following the rightmost slash "/", or the entire path if no slash is present) is removed and the embedded URL's path is appended in its place. The following operations are then applied, in order, to the new path:" 

así que eso lo explica. el baseURL necesita terminar en una / y la url relativa no debe comenzar con a /

Aquí tienes dos problemas:

En primer lugar, la cadena /files/search es una ruta absoluta ya que comienza con una barra diagonal. Resolverlo contra cualquier URL existente ignorará la ruta existente.

En segundo lugar, https://api.service.com/v1 no tiene una barra inclinada para indicar que es un directory. Cualquier cadena resuelta en contra siempre ignorará la porción v1 .

Para concluir, necesita ese combo de una ruta relativa ( files/search ) y URL base de directory: https://api.service.com/v1/ .

Otro ejemplo:

 //it's right NSURL *url = [NSURL URLWithString:@"getValidNumber" relativeToURL:[NSURL URLWithString:@"http://dns.test.com:22009/service/"]]; //error NSURL *url = [NSURL URLWithString:@"getValidNumber" relativeToURL:[NSURL URLWithString:@"dns.test.com:22009/service/"]]; //error NSURL *url = [NSURL URLWithString:@"/getValidNumber" relativeToURL:[NSURL URLWithString:@"http://dns.test.com:22009/service"]]; 

`El 'http: //' es necesario para usar este método.