2016-04-12 5 views
0

多くの形式のURLを表す文字列を取得し、標準化してURL仕様に準拠させる必要があります。Objective CのURL文字列を解析するきれいで堅牢な方法

URL文字列にスキームが含まれていないか、 'http'または 'https'以外のスキームがある場合は、デフォルトスキームを使用する必要があります。

そこで私は次のように出力してNSStringの

#define DEFAULT_SCHEME @"http" 

@implementation NSString (standardiseUrlFormat) 

- (NSString*)standardiseUrlFormat { 
    NSURLComponents *components = [NSURLComponents componentsWithString:self]; 
    BOOL hasScheme = components.scheme != nil; 

    // If no scheme or an invalid scheme is provided, default to http 
    if (!hasScheme) { 
     // We have to use string concatenation here because NSURLComponents will 
     // put the hostname as the path if there is no scheme 
     return [NSString stringWithFormat:@"%@://%@", DEFAULT_SCHEME, self]; 
    } 

    // Now we know that a scheme exists, check if it is a correct scheme 
    if (![components.scheme isEqualToString:@"http"] && 
     ![components.scheme isEqualToString:@"https"]) { 
     // Overwrite scheme if not supported 
     components.scheme = DEFAULT_SCHEME; 
    } 

    return [components string]; 
} 

@end 

にこのカテゴリーに終わった私はNSURLComponentsを使用していたが、仕組みが提供されていない場合には、パス

NSURLComponents *components = [NSURLComponents componentsWithString:@"www.google.com.au"]; 
components.scheme = @"http"; 
NSLog(@"1: %@", components.path); 
NSLog(@"2: %@", components.host); 
NSLog(@"3: %@", components.string); 

testtest[2619:869020] 1: www.google.com.au 
testtest[2619:869020] 2: ((null)) 
testtest[2619:869020] 3: http:www.google.com.au <-- Invalid 

としてホストを解析

NSLog(@"1: %@", [@"http://www.google.com" standardiseUrlFormat]); 
NSLog(@"2: %@", [@"www.google.com" standardiseUrlFormat]); 
NSLog(@"3: %@", [@"https://www.google.com" standardiseUrlFormat]); 
NSLog(@"4: %@", [@"https://www.google.com/some_path" standardiseUrlFormat]); 
NSLog(@"5: %@", [@"www.google.com/some_path" standardiseUrlFormat]); 

testtest[7411:944022] 1: http://www.google.com 
testtest[7411:944022] 2: http://www.google.com 
testtest[7411:944022] 3: https://www.google.com 
testtest[7411:944022] 4: https://www.google.com/some_path 
testtest[7411:944022] 5: http://www.google.com/some_path 

誰もが2つの方法を使用しないクリーナーソリューションを提案できますかs(NSURLComponentsと文字列連結)を使用して文字列を構成しますか?

+0

これはかなり厳しいです。私は、mailto://[email protected]をhttp://[email protected]に変更することは意味をなしません。またはftp、またはfile://、または基本的にhttp(s)以外のもの。 – Eiko

+1

それは本当ですが、この場合は、入力URL文字列がhttpまたはhttpsのスキームを持つと仮定されている必要があります –

+0

単に文字列置換操作をしないのはなぜですか?最初の "://"を探し、その前にあるものをhttp(httpsでない限り)で置き換えます。見つからない場合は、前面に挿入します。 – Eiko

答えて

1

文字列の連結は一切使用しないでください。 NSURLComponentsをに、のNSURLを使用してください。それが何のためだ。たとえば、schemeが好きではない場合は、と設定してください。schemeにしてください。

EDIT私はこのURLがホストレスURLであることが検出されたと思います。

let s = "www.apple.com/whatever" as NSString 
let arr = s.pathComponents 
let c = NSURLComponents() 
c.scheme = "http" 
c.host = arr[0] 
c.path = "/" + (Array(arr.dropFirst()) as NSArray).componentsJoinedByString("/") 

おそらくこれは実行できません。実際には、スキームのないURLは多かれ少なかれURLではないという問題があります。

+0

問題は、NSURLComponentsがスキームを持たない場合、URLを正しく解析しないことです。文字列全体をパスコンポーネントとして置き、残りのコンポーネントはゼロにします。 編集:私は新しいNSURLComponentsオブジェクトを作成して手動で構築できると思いますが、もっと複雑なコンポーネントを分離するために独自の解析を行う必要があります。 –

+0

まあ、上記の私のさらなる提案を参照してください、しかし、おそらくそこに方法はありません... – matt

関連する問題