2008-09-05 61 views
6

在我正在寫我有一些這樣的代碼的應用程序:打開一個非標準的網址,以便在Cocoa程序

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失敗,返回

處理此問題的「正確」方法是什麼?我是否需要解析字符串並正確編碼參數?還是在Cocoa有一些聰明的方法爲我做了所有的辛苦工作?

回答

2

我認爲這裏的行爲是正確的,因爲%d不是一個URL的有效成分(%是逃避,而是需要兩個十六進制字符遵循它)。

你不能只是URL編碼URL作爲給你,因爲那將編碼/ s和?的爲好,你不想要的。

所以,問題是,這裏有什麼正確的行爲?

也許你會希望它變成...

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

(即%被編碼爲%的在URL編碼版本,所以當方法獲取輸入,它看到的被設置爲%d)

我不認爲有任何庫函數將做那種事情對你來說,因爲沒有「正確」的方式來做到這一點。關於他唯一可以做的正確的事情就是返回一個錯誤信息,說你給的網址是無效的(就像URLWithString是)


如果您想嘗試處理輸入,我想你需要在URL中搜索任何未緊跟兩個十六進制字符的%符號,然後在該情況下用%25替換%。對於正則表達式,這應該是完全可能的,儘管我懷疑如果您的URL開始包含ASCII字符集之外的字符的編碼版本,則可能會有一些額外的複雜性。

1

不幸的是,你需要比什麼更聰明由蘋果公司提供:

stringByAddingPercentEscapesUsingEncoding: 

這將轉義所有無效的URL字符,以便「http://foo.com/hey%20dude/」,這是有效的,成爲「http://foo.com/嘿%2520dud /「,這不是我們想要的。

根據蘋果文檔:http://developer.apple.com/library/mac/documentation/CoreFOundation/Reference/CFURLRef/Reference/reference.html#//apple_ref/c/func/CFURLCreateStringByAddingPercentEscapes

我由NSURL類別,它做正確的事,並與奇數串作品如具有部分編碼的人(即「http://foo.com/hey哥們/ I %20do%20IT /「)。

下面是代碼:

@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的。

相關問題