2013-05-16 4 views
21

Sto provando a implementare un'app iOS, che utilizza RestKit. In tutti gli esempi che ho visto finora il seguente codice viene utilizzato per creare gli URL:NSURL URLWithString: relativeToURL: è il clipping dell'URL relativo

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

Ma poi [relativeURL absoluteString] tornerà https://api.service.com/files/search.

Così ho provato un paio di esempi:

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

e questo è l'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 

Quindi l'unico esempio tornando quello che voglio è # 4. Qualcuno può spiegare perché?

risposta

45

ho letto [RFC1808] che definisce l'algoritmo normativo per la risoluzione di URL relativi

2 problemi:

  1. l'url relativa non può iniziare con una/o è considerato come assoluto:

    Step 4: If the embedded URL path is preceded by a slash "/", the 
        path is not relative and we skip to Step 7." 
    
  2. quando l'URL di base termina con una non-barra. tutto dall'ultima barra sul viene saltato

    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:" 
    

in modo che lo spiega. il baseURL ha bisogno di finire in un/e l'url relativa non dovrebbe iniziare con una/

+1

@downvoter spiegare perché ... è perché il leader /? Ottengo che e quindi modificato e votato fino mike .. ma per favore commenti di ogni volta che si Answer –

+3

ancora: ultima giù elettore voi prego lasciare un commento in modo da poter risolvere il problema, se necessario –

+2

il baseURL ha bisogno di finire in un/e l'url relativo non dovrebbe iniziare con/questo è assolutamente corretto :). Ho avuto qualche problema con l'url di base e il percorso. Puoi aggiungere il link per [RFC1808] – Johnykutty

8

Hai due problemi qui:

In primo luogo, la stringa /files/search è un assoluto percorso dal momento che inizia con una barra . Risolvendolo contro qualsiasi URL esistente ignorerà il percorso esistente.

In secondo luogo, https://api.service.com/v1 non ha una barra finale per indicare che si tratta di una directory. Qualsiasi stringa risolta contro di essa ignorerà sempre la porzione v1.

Per concludere, è necessaria la combinazione di un percorso relativo - files/search - e l'URL di base della directory - https://api.service.com/v1/.

0

Un altro esempio:

//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"]]; 

` Il 'http: //' è necessario per utilizzare questo metodo.