網(wǎng)上有個公開的天氣接口:天氣 ,點進(jìn)其中的getSupportCityDataset接口六水,用這個接口為例寫一下iOS上的HTTP請求的寫法桨啃。 這里面提供了get踩蔚、post請求的格式要求不瓶。
1禾嫉、get:?1234567891011121314
NSString
* URLString = @"http://webservice.webxml.com.cn/WebServices/WeatherWS.asmx/getSupportCityDataset?theRegionCode=廣東";
NSURL
* URL = [NSURL URLWithString:[URLString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
NSURLRequest
* request = [[NSURLRequest alloc]initWithURL:URL];
NSURLResponse
* response = nil;
NSError
* error = nil;
NSData
* data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
if
(error) {
NSLog(@"error:
%@",[error
localizedDescription]);
}else{
NSLog(@"response
: %@",response);
NSLog(@"backData
: %@",[[NSString
alloc]initWithData:data encoding:NSUTF8StringEncoding]);
}
get方法的請求參數(shù)是放在長長的URL字符串里面,這里只需要一個參數(shù)蚊丐,就是地區(qū)的編號或名字熙参,通過這個參數(shù),服務(wù)器返回屬于這個區(qū)域內(nèi)支持天氣查找的城市列表麦备。如果有更多的參數(shù)也是放在URL字符串里面尊惰,至于參數(shù)的組織方式讲竿,就看服務(wù)器的要求了。用字符串構(gòu)建NSURL弄屡,最好在使用URLWithString的時候把原字符串進(jìn)行一下UTF8轉(zhuǎn)碼,關(guān)于為何要轉(zhuǎn)碼鞋诗,看下這里第一部分膀捷。然后NSURL對象構(gòu)建NSURLRequest,使用NSURLConnection的同步方法削彬,傳入request對象就可以通過get方法獲取數(shù)據(jù)全庸。這里有個NSError對象地址傳入,用于做錯誤判斷融痛,網(wǎng)絡(luò)的實際情況是多變的壶笼,必須要考慮請求錯誤的情況,否則可能導(dǎo)致程序奔潰雁刷。
2覆劈、post:?123456789101112131415161718192021
NSString * URLString = @"http://webservice.webxml.com.cn/WebServices/WeatherWS.asmx/getSupportCityString";? ? NSURL * URL = [NSURL URLWithString:[URLString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];? ? ? ? NSString * postString = @"theRegionCode=廣東";? ? NSData * postData = [postString dataUsingEncoding:NSUTF8StringEncoding];? //將請求參數(shù)字符串轉(zhuǎn)成NSData類型? ? ? ? NSMutableURLRequest * request = [[NSMutableURLRequest alloc]init];? ? [request setHTTPMethod:@"post"];//指定請求方式? ? [request setURL:URL]; //設(shè)置請求的地址? ? [request setHTTPBody:postData];? //設(shè)置請求的參數(shù)? ? ? ? NSURLResponse * response;? ? NSError * error;? ? NSData * backData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];? ? ? ? if(error) {? ? ? ? NSLog(@"error : %@",[error localizedDescription]);? ? }else{? ? ? ? NSLog(@"response : %@",response);? ? ? ? NSLog(@"backData : %@",[[NSString alloc]initWithData:backData encoding:NSUTF8StringEncoding]);? ? }post方式的時候參數(shù)是放在HTTPBody里面的,而且需要將字符串轉(zhuǎn)碼成響應(yīng)的NSData類型沛励,在接口文檔里一般都有指出轉(zhuǎn)碼方式责语,需要按指定方式轉(zhuǎn)碼,這里的UTF8目派,也有g(shù)b2312的坤候。request構(gòu)建好了之后,和get方法一樣使用NSURLConnection請求數(shù)據(jù)企蹭。3白筹、同步和異步請求:一般網(wǎng)絡(luò)請求都需要一段時間,哪怕數(shù)據(jù)再少谅摄、網(wǎng)絡(luò)再好徒河,都會有一段時間,而且很多時候必須考慮在網(wǎng)絡(luò)不好的時候的app狀態(tài)螟凭。使用同步請求只需安心等待數(shù)據(jù)就可以虚青,不需要做額外操作,上面兩例都是同步請求螺男,connection調(diào)用方法后會把返回請求的數(shù)據(jù)棒厘,無需做什么其他事。但是同步會阻塞線程下隧,如果通過點擊button來發(fā)起請求奢人,那么按鈕會停留在highLight狀態(tài)直到請求結(jié)束,會造成一種app卡住淆院、死機(jī)的感覺何乎,很不好。異步get:?123456NSString * URLString = @"http://webservice.webxml.com.cn/WebServices/WeatherWS.asmx/getSupportCityDataset?theRegionCode=廣東";? ? NSURL * URL = [NSURL URLWithString:[URLString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];? ? ? ? NSURLRequest * request = [[NSURLRequest alloc]initWithURL:URL];? ? ? ? _connection = [[NSURLConnection alloc]initWithRequest:request delegate:self];? (1)異步post類似,不再是使用NSURLConnection調(diào)用方法直接得到數(shù)據(jù)支救,而是使用(1)位置方法構(gòu)建一個NSURLConnection對象抢野,這個方法會默認(rèn)開始請求數(shù)據(jù)。接下來關(guān)鍵就是靠委托了各墨。因為請求的時間未知指孤,所以使用委托模式的回調(diào)作用,在數(shù)據(jù)回來是調(diào)用協(xié)議方法贬堵。post和get委托方法處理一樣恃轩。協(xié)議方法:要注意的是這里有兩個委托:NSURLConnectionDataDelegate和NSURLConnectionDelegate,前一個繼承于后一個黎做,獲取數(shù)據(jù)的方法是定義在前一個委托里面的叉跛,所以只要遵循NSURLConnectionDataDelegate就可以了。一般用到四個委托方法:?12345678910111213141516171819202122232425262728293031
//接受到respone,這里面包含了HTTP請求狀態(tài)碼和數(shù)據(jù)頭信息蒸殿,包括數(shù)據(jù)長度筷厘、編碼格式等
-(void)connection:(NSURLConnection
*)connection didReceiveResponse:(NSURLResponse *)response{ NSLog(@"response
= %@",response);
_backData = [[NSMutableData alloc]init];
}
//接受到數(shù)據(jù)時調(diào)用,完整的數(shù)據(jù)可能拆分為多個包發(fā)送伟桅,每次接受到數(shù)據(jù)片段都會調(diào)用這個方法敞掘,所以需要一個全局的NSData對象,用來把每次的數(shù)據(jù)拼接在一起
-(void)connection:(NSURLConnection
*)connection didReceiveData:(NSData *)data{
[_backData
appendData:data];
}
//數(shù)據(jù)接受結(jié)束時調(diào)用這個方法楣铁,這時的數(shù)據(jù)就是獲得的完整數(shù)據(jù)了玖雁,可以使用數(shù)據(jù)做之后的處理了
-(void)connectionDidFinishLoading:(NSURLConnection
*)connection{
NSLog(@"%@",[[NSString
alloc]initWithData:_backData encoding:NSUTF8StringEncoding]);
}
//這是請求出錯是調(diào)用,錯誤處理不可忽視
-(void)connection:(NSURLConnection
*)connection didFailWithError:(NSError *)error{
if
(error.code == NSURLErrorTimedOut) {
NSLog(@"請求超時");
}
NSLog(@"%@",[error
localizedDescription]);
}
最后盖腕,請求可以設(shè)置超時時間:
NSURLRequest
* request = [[NSURLRequest alloc]initWithURL:URL cachePolicy:0
timeoutInterval:8.0];
或者:
NSMutableURLRequest
* request = [[NSMutableURLRequest alloc]initWithURL:URL];
[request
setTimeoutInterval:8.0];
請求時間超過所設(shè)置的超時時間赫冬,會自動調(diào)用
-(void)connection:(NSURLConnection
*)connection didFailWithError:(NSError *)error
但是有個問題是怎么把判斷是超時導(dǎo)致的請求失敗,上面的例子里已經(jīng)寫了溃列,可以根據(jù)返回的error的code進(jìn)行判斷劲厌。了解不同情況的請求失敗,可以更好的給用戶提示听隐。