6

私が書いているアプリケーションには、次のようなコードがあります。

NSWorkspace* ws = [NSWorkspace sharedWorkspace];
NSString* myurl = @"http://www.somewebsite.com/method?a=%d";

NSURL* url = [NSURL URLWithString:myurl];

[ws openURL:url];

主な違いは、myurlが自分の制御の及ばないところから来ていることです。URL の %d は完全に正しくないことに注意してください。これは、URLWithString が失敗してnilが返されることを意味します。

これを処理する「正しい」方法は何ですか?文字列を解析して引数を適切にエンコードする必要がありますか? それとも、すべての面倒な作業をすべてやってくれる賢い方法が Cocoa にあるのでしょうか?

4

3 に答える 3

8

これがまさにあなたが探しているものかどうかはわかりませんが、NSString には URL をサニタイズするメソッドがあります。

stringByAddingPercentEscapesUsingEncoding:

于 2008-09-05T16:21:18.100 に答える
2

%d は URL の有効なコンポーネントではないため、ここでの動作は正しいと思います (% はエスケープですが、その後に 2 つの 16 進文字が続くことを想定しています)。

与えられた URL を単に URL エンコードすることはできません。これは、望ましくない /s と ?s もエンコードしてしまうためです。

では、問題は、ここでの正しい動作は何ですか?

おそらく、あなたはそれを次のように変えたいと思うでしょう...

http://www.somewebsite.com/method?a=%25d

(つまり、% は URL 内の % のエンコードされたバージョンにエンコードされるため、メソッドが入力を取得すると、a が %d に設定されていると見なされます)

「正しい」方法がないため、そのようなことを行うライブラリ関数はないと思います。彼についてあなたができる唯一の正しいことは、指定された URL が無効であることを示すエラー メッセージを返すことです (URLWithString がそうであるように)。


入力を処理したい場合は、2 つの 16 進文字がすぐ後に続かない % 記号を URL で検索し、その場合は % を %25 に置き換える必要があると思います。これは正規表現で十分可能ですが、URL に ASCII 文字セット以外のエンコードされたバージョンの文字が含まれ始めると、さらに複雑になる可能性があると思います。

于 2008-09-05T14:18:27.007 に答える
1

残念ながら、Appleが提供するものよりも賢くする必要があります。

stringByAddingPercentEscapesUsingEncoding:

これにより、すべての無効なURL文字がエスケープされ、有効な「http://foo.com/hey%20dude/」が「http://foo.com/hey%2520dud/」になります。これは、私たちが望むものではありません。 。

アップルのドキュメントによると:http://developer.apple.com/library/mac/documentation/CoreFOundation/Reference/CFURLRef/Reference/reference.html#//apple_ref/c/func/CFURLCreateStringByAddingPercentEscapes

私は、正しいことを行い、部分的なエンコーディングを使用するような奇妙な文字列(つまり、「http://foo.com/hey dude / i%20do%20it /」)で機能するNSURLカテゴリを作成しました。

コードは次のとおりです。

@interface NSURL (SmartEncoding)
+ (NSURL *)smartURLWithString:(NSString *)str;
@end

@implementation NSURL (SmartEncoding)

+ (NSURL *)smartURLWithString:(NSString *)str
{
    CFStringRef preprocessed = CFURLCreateStringByReplacingPercentEscapesUsingEncoding(NULL, (CFStringRef)str, CFSTR(""), kCFStringEncodingUTF8);
    if (!preprocessed) 
        preprocessed = CFURLCreateStringByReplacingPercentEscapesUsingEncoding(NULL, (CFStringRef)str, CFSTR(""), kCFStringEncodingASCII);

    if (!preprocessed)
        return [NSURL URLWithString:str];

    CFStringRef sanitized = CFURLCreateStringByAddingPercentEscapes(NULL, preprocessed, NULL, NULL, kCFStringEncodingUTF8);
    CFRelease(preprocessed);
    NSURL *result = (NSURL*)CFURLCreateWithString(NULL, sanitized, NULL);
    CFRelease(sanitized);
    return [result autorelease];
}

@end

UTF8文字列でエンコードされたものとASCIIのもので正常に動作します。

于 2011-12-29T09:18:14.060 に答える