web-dev-qa-db-ja.com

NSURL URLWithString:relativeToURL:相対URLをクリッピングしています

RestKitを使用するiOSアプリを実装しようとしています。これまで見てきたすべての例で、次のコードを使用してURLを作成しています。

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

しかしその後 [relativeURL absoluteString] 戻ります https://api.service.com/files/search

だから私はいくつかの例を試しました:

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

そしてこれは出力です:

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

したがって、私が欲しいものを返す唯一の例は#4です。誰かが理由を説明できますか?

23
Pipo

私は読んだ [RFC1808] これは相対URLを解決するための規範的なアルゴリズムを定義しています

2つの問題:

  1. 相対URLが/で始まらない場合や、絶対URLと見なされる場合があります。

    Step 4: If the embedded URL path is preceded by a slash "/", the
       path is not relative and we skip to Step 7."
    
  2. ベースURLがスラッシュ以外で終わる場合。最後のスラッシュ以降はすべてスキップされます

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

それがそれを説明します。 baseURLは/で終わる必要があり、相対URLは/で始まるべきではありません

51
Daij-Djan

ここには2つの問題があります。

まず、文字列/files/searchはスラッシュで始まるため、絶対パスです。既存のURLに対してそれを解決すると、既存のパスは無視されます。

次に、https://api.service.com/v1には、ディレクトリであることを示す末尾のスラッシュがありません。それに対して解決された文字列は、常にv1部分を無視します。

結論として、相対パス— files/search —とディレクトリベースURL — https://api.service.com/v1/の組み合わせが必要です。

9
Mike Abdullah

もう一つの例:

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

`このメソッドを使用するには、「http://」が必要です。

0
tunnySu