web-dev-qa-db-fra.com

NSURL URLWithString: relativeToURL: isole l'URL relative

J'essaie d'implémenter une application iOS qui utilise RestKit. Dans tous les exemples que j'ai vus jusqu'à présent, le code suivant est utilisé pour créer les URL:

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

Mais alors [relativeURL absoluteString] retournera https://api.service.com/files/search.

J'ai donc essayé quelques exemples:

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

Et voici le résultat:

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

Donc, le seul exemple renvoyant ce que je veux est le n ° 4. Quelqu'un peut-il expliquer pourquoi?

22
Pipo

Je lis [RFC1808] qui définit l'algorithme normatif pour résoudre les URL relatives

2 questions:

  1. l'URL relative peut ne pas commencer par un/ou elle est considérée comme absolue: 

    Step 4: If the embedded URL path is preceded by a slash "/", the
       path is not relative and we skip to Step 7."
    
  2. lorsque l'URL de base se termine par un non-slash. tout est ignoré depuis la dernière barre oblique

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

alors ça l'explique. le baseURL doit se terminer par un/et l'URL relative ne doit pas commencer par un /

47
Daij-Djan

Vous avez deux problèmes ici:

Premièrement, la chaîne /files/search est un chemin absolute car elle commence par une barre oblique. Le résoudre avec n'importe quelle URL existante ignorera le chemin existant.

Deuxièmement, https://api.service.com/v1 n'a pas de barre oblique finale pour indiquer que c'est un répertoire. Toute chaîne résolue avec elle ignorera toujours la portion v1.

Pour conclure, vous avez besoin de cette combinaison d'un chemin relatif - files/search - et d'une URL de base de répertoire - https://api.service.com/v1/.

8
Mike Abdullah

Un autre exemple:

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

` Le 'http: //' est nécessaire pour utiliser cette méthode.

0
tunnySu