資料均來自互聯網,轉載時請務必以超鏈接形式標明文章 原始出處 、作者信息和本聲明。否則將追究法律責任。
人魔七七:http://www.cnblogs.com/qiqibo/
對於我們IOS開發者來說,我們最重要的是訪問網絡的資源,數據都是服務器提供給我們的。我們一般會通過API訪問我們網絡資源,一般一個資源可能對應很多URL,但是一個URL只對應一個資源不能對應很多資源。但是也有一些例外,例如當hostName引用一個模糊的主機。在URL加載IOS系統中,NSURL對象被用來管理URL對象。
一個URL通常由下面幾個部分組成如下圖:
protocol:這個協議組成部分指定應用層協議來和服務器通信。你可能了解有其他的協議比如ftp協議相對於http協議。http協議的統治地位因為pre-http協議遭到挑戰。另一個經常用的協議是file協議,file協議是IOS的app用來在沙盒檢索數據的協議。如果你用NSURL但是沒有用到其他的協議,默認用的就是這個協議。
Credentials:Credentials:一些http服務器支持用戶憑證的URL對基本身份驗證是一個挑戰。如上圖所示這個憑證組成部分包含了用戶名密碼的身份驗證,這種格式索然不是很普遍,考慮比其他方式驗證更不安全。
Hostname:這個組件包含TCP的hostname和IP地址關於主機包含它想要的資源。如果URL的協議是file那么應該省略這些東西。一個URL針對一個獨立的資源被打破這是個例外當相對的和本地的主機名字被使用。例如你的主機名字作為hostname,這個URL關聯本地機器然后用同一個URL可以關聯不同的資源在不同的機器上。
Port:這個URL port部分指定這個客戶端應該連接哪個端口。如果忽略了,那么客戶端將要用默認的端口為這個協議例如http的80端口,https的443端口。最好的實踐是用這些端口值當應用運行在外網因為有些網絡代理和防火牆將阻塞非標准端口值因為安全或者隱私的原因。
Absolute-path:這個絕對路徑部分指定網絡資源的路徑,如果http服務器有可能有目錄樹。這個絕對路徑可能包括任意數量的路徑組件每個組件用"/"字符分隔。一個絕對路徑可能不包含一個問號,空格,回車,或者換行符字符。有一些Rest服務用路徑部分作為傳遞值來獨特標識一個實體存儲到數據庫的一種手段。例如,一個路徑/customer/456/address/0將要指定標識符456索引在0的地址。
Query:URl的最后部分是查詢字符串。這個值是從絕對路徑用?隔開的。多個參數每個參數用&分隔。查詢字符串不能包含回車空格換行字符。
因為決定路徑和拼接的查詢字符串的內容是有限制的。URL通常用百分比編碼。rfc 3986指定了URL百分比編碼的具體細節IOS提供一個字符串對象的方法來執行URL編碼。下面代碼片段顯示如何編碼。
NSString *urlString = @"http://myhost.com?query=This is a question"; NSString *encoded = [urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
這個編碼的結果是:http://myhost.com?query=This%20is%20a%20question.每個空格被替換成%20序列。這個編碼和URL編碼不一樣之處在於不編碼&字符。從而使URL參數完好無損。URL編碼將要編碼&符號,問號,和其他標點符號。如果你查詢字符串包含這些字符串。你需要實現更徹底的編碼方法。目的是把這些字符轉化為%+ASCII這種模式代替。
你可以專門把這些符號剔除出來。
於是網上找了一個解決方案(
(@ http://www.cnblogs.com/meyers/archive/2012/04/26/2471669.html)
)
@implementation NSURL (mm) + (NSURL *)URLWithBaseString:(NSString *)baseString parameters:(NSDictionary *)parameters{ NSMutableString *urlString =[NSMutableString string]; //The URL starts with the base string[urlString appendString:baseString]; [urlString appendString:baseString]; NSString *escapedString; NSInteger keyIndex = 0; for (id key in parameters) { //First Parameter needs to be prefixed with a ? and any other parameter needs to be prefixed with an & if(keyIndex ==0) { escapedString =(NSString*)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,(CFStringRef)[parameters valueForKey:key], NULL, CFSTR(":/?#[]@!$&’()*+,;="), kCFStringEncodingUTF8); [urlString appendFormat:@"?%@=%@",key,escapedString]; [escapedString release]; }else{ escapedString =(NSString*)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,(CFStringRef)[parameters valueForKey:key], NULL, CFSTR(":/?#[]@!$&’()*+,;="), kCFStringEncodingUTF8); [urlString appendFormat:@"&%@=%@",key,escapedString]; [escapedString release]; } keyIndex++; } return [NSURL URLWithString:urlString]; } @end
例如: NSString * baseString = @"http://twitter.com/statuses/update.xml";
NSDictionary*dictionary=[NSDictionary dictionaryWithObjectsAndKeys:@"This is my status",@"status",@"meng ya", @"meyers",nil]; NSURL * url = [NSURL URLWithBaseString:baseString parameters:dictionary]; NSLog(@"the url : %@", url);
輸出:the url : http://twitter.com/statuses/update.xml?status=This%20is%20my%20status&meyers=meng%20ya