iOS開發(fā)網(wǎng)絡篇—NSURLConnection基本使用

iOS開發(fā)網(wǎng)絡篇—NSURLConnection基本使用

一低散、NSURLConnection的常用類

(1)NSURL:請求地址

(2)NSURLRequest:封裝一個請求鳍烁,保存發(fā)給服務器的全部數(shù)據(jù)啊楚,包括一個NSURL對象叮趴,請求方法逊彭、請求頭然磷、請求體....

(3)NSMutableURLRequest:NSURLRequest的子類

(4)NSURLConnection:負責發(fā)送請求紫谷,建立客戶端和服務器的連接挣输。發(fā)送NSURLRequest的數(shù)據(jù)給服務器纬凤,并收集來自服務器的響應數(shù)據(jù)

二、NSURLConnection的使用

1.簡單說明

使用NSURLConnection發(fā)送請求的步驟很簡單

(1)創(chuàng)建一個NSURL對象撩嚼,設置請求路徑(設置請求路徑)

(2)傳入NSURL創(chuàng)建一個NSURLRequest對象停士,設置請求頭和請求體(創(chuàng)建請求對象)

(3)使用NSURLConnection發(fā)送NSURLRequest(發(fā)送請求)

2.代碼示例

(1)發(fā)送請求的三個步驟:

1.設置請求路徑

2.創(chuàng)建請求對象

3.發(fā)送請求

3.1發(fā)送同步請求(一直在等待服務器返回數(shù)據(jù),這行代碼會卡住完丽,如果服務器恋技,沒有返回數(shù)據(jù),那么在主線程UI會卡住不能繼續(xù)執(zhí)行操作)有返回值

3.2發(fā)送異步請求:沒有返回值

說明:任何NSURLRequest默認都是get請求逻族。

(2)發(fā)送同步請求代碼示例:

1//2//YYViewController.m3//01-NSURLConnection的使用(GET)4//5//Created by apple on 14-6-28.6//Copyright (c) 2014年 itcase. All rights reserved.7//89#import"YYViewController.h"10#import"MBProgressHUD+MJ.h"1112@interfaceYYViewController ()13@property (weak, nonatomic) IBOutlet UITextField *username;14@property (weak, nonatomic) IBOutlet UITextField *pwd;15-(IBAction)login;1617@end1819@implementationYYViewController2021-(IBAction)login {22//1.提前的表單驗證23if(self.username.text.length==0) {24[MBProgressHUD showError:@"請輸入用戶名"];25return;26}27if(self.pwd.text.length==0) {28[MBProgressHUD showError:@"請輸入密碼"];29return;30}31//2.發(fā)送請求給服務器(帶上賬號和密碼)32//添加一個遮罩蜻底,禁止用戶操作33//[MBProgressHUD showMessage:@"正在努力加載中...."];34//GET請求:請求行\(zhòng)請求頭\請求體35//36//1.設置請求路徑37NSString *urlStr=[NSString stringWithFormat:@"http://192.168.1.53:8080/MJServer/login?username=%@&pwd=%@",self.username.text,self.pwd.text];38NSURL *url=[NSURL URLWithString:urlStr];39//2.創(chuàng)建請求對象40NSURLRequest *request=[NSURLRequest requestWithURL:url];41//3.發(fā)送請求42//發(fā)送同步請求,在主線程執(zhí)行43NSData *data=[NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];44//(一直在等待服務器返回數(shù)據(jù)聘鳞,這行代碼會卡住薄辅,如果服務器沒有返回數(shù)據(jù),那么在主線程UI會卡住不能繼續(xù)執(zhí)行操作)45NSLog(@"--%d--",data.length);46}47@end

模擬器情況:

打印服務器返回的信息:

補充說明:

1.提前的表單驗證

2.發(fā)送請求給服務器(帶上賬號和密碼)

GET請求:請求行\(zhòng)請求頭\請求體

注意:GET請求中不存在請求體抠璃,因為所有的信息都寫在URL里面站楚。在IOS里面,請求行和請求頭都不用寫搏嗡。

(3)發(fā)送異步請求

發(fā)送異步請求有兩種方式:

1)使用block回調

2)代理

A.使用block回調方法發(fā)送異步請求

使用block回調代碼示例:

1//2//YYViewController.m3//01-NSURLConnection的使用(GET)4//5//Created by apple on 14-6-28.6//Copyright (c) 2014年 itcase. All rights reserved.7//89#import"YYViewController.h"10#import"MBProgressHUD+MJ.h"1112@interfaceYYViewController ()13@property (weak, nonatomic) IBOutlet UITextField *username;14@property (weak, nonatomic) IBOutlet UITextField *pwd;15-(IBAction)login;1617@end1819@implementationYYViewController2021-(IBAction)login {22//1.提前的表單驗證23if(self.username.text.length==0) {24[MBProgressHUD showError:@"請輸入用戶名"];25return;26}27if(self.pwd.text.length==0) {28[MBProgressHUD showError:@"請輸入密碼"];29return;30}31//2.發(fā)送請求給服務器(帶上賬號和密碼)32//添加一個遮罩窿春,禁止用戶操作33[MBProgressHUD showMessage:@"正在努力加載中...."];3435//36//1.設置請求路徑37NSString *urlStr=[NSString stringWithFormat:@"http://192.168.1.53:8080/MJServer/login?username=%@&pwd=%@",self.username.text,self.pwd.text];38NSURL *url=[NSURL URLWithString:urlStr];3940//2.創(chuàng)建請求對象41NSURLRequest *request=[NSURLRequest requestWithURL:url];4243//3.發(fā)送請求44//3.1發(fā)送同步請求,在主線程執(zhí)行45//NSData *data=[NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];46//(一直在等待服務器返回數(shù)據(jù)采盒,這行代碼會卡住旧乞,如果服務器沒有返回數(shù)據(jù),那么在主線程UI會卡住不能繼續(xù)執(zhí)行操作)4748//3.1發(fā)送異步請求49//創(chuàng)建一個隊列(默認添加到該隊列中的任務異步執(zhí)行)50//NSOperationQueue *queue=[[NSOperationQueue alloc]init];51//獲取一個主隊列52NSOperationQueue *queue=[NSOperationQueue mainQueue];53[NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {54NSLog(@"--block回調數(shù)據(jù)--%@---%d", [NSThread currentThread],data.length);55//隱藏HUD纽甘,刷新UI的操作一定要放在主線程執(zhí)行56[MBProgressHUD hideHUD];5758//解析data59/*60{"success":"登錄成功"}61{"error":"用戶名不存在"}62{"error":"密碼不正確"}63*/64NSDictionary *dict=[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil];65NSLog(@"%@",dict);6667//判斷后良蛮,在界面提示登錄信息68NSString *error=dict[@"error"];69if(error) {70[MBProgressHUD showError:error];71}else72{73NSString *success=dict[@"success"];74[MBProgressHUD showSuccess:success];75}76}];77NSLog(@"請求發(fā)送完畢");78}79@end

模擬器情況(注意這里使用了第三方框架):

打印查看:

代碼說明:

block代碼段:當服務器有返回數(shù)據(jù)的時候調用會開一條新的線程去發(fā)送請求,主線程繼續(xù)往下走悍赢,當拿到服務器的返回數(shù)據(jù)的數(shù)據(jù)的時候再回調block决瞳,執(zhí)行block代碼段货徙。這種情況不會卡住主線程。

隊列的作用:決定這個block操作放在哪個線程執(zhí)行皮胡?

刷新UI界面的操作應該放在主線程執(zhí)行痴颊,不能放在子線程,在子線程處理UI相關操作會出現(xiàn)一些莫名的問題屡贺。

提示:

(1)創(chuàng)建一個操作蠢棱,放在NSOperation隊列中執(zhí)行,默認是異步執(zhí)行的甩栈。

(2)mainqueue ? 返回一個和主線程相關的隊列泻仙,即主隊列。

新的問題:如果向服務器發(fā)送請求量没,卻并沒有拿到數(shù)據(jù)玉转,那么程序會崩潰(data不能為空)

改進代碼:

1NSOperationQueue *queue=[NSOperationQueue mainQueue];2[NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {3//當請求結束的時候調用(有兩種結果,一個是成功拿到數(shù)據(jù)殴蹄,也可能沒有拿到數(shù)據(jù)究抓,請求失敗)4NSLog(@"--block回調數(shù)據(jù)--%@---%d", [NSThread currentThread],data.length);5//隱藏HUD袭灯,刷新UI的操作一定要放在主線程執(zhí)行6[MBProgressHUD hideHUD];78//解析data9/*10{"success":"登錄成功"}11{"error":"用戶名不存在"}12{"error":"密碼不正確"}13*/14if(data) {//請求成功15NSDictionary *dict=[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil];16NSLog(@"%@",dict);1718//判斷后刺下,在界面提示登錄信息19NSString *error=dict[@"error"];20if(error) {21[MBProgressHUD showError:error];22}else23{24NSString *success=dict[@"success"];25[MBProgressHUD showSuccess:success];26}27}else//請求失敗28{29[MBProgressHUD showError:@"網(wǎng)絡繁忙,請稍后重試稽荧!"];30}3132}];

解析data

//解析data/*{"success":"登錄成功"}

{"error":"用戶名不存在"}

{"error":"密碼不正確"}*/

說明:使用NSJSONSerialization 返回的對象橘茉,取決于最外層是什么,如果是{}那就是字典姨丈,[]那就是數(shù)組等捺癞。

補充說明:

首先確定請求路徑,然后創(chuàng)建請求對象(默認發(fā)送的時get請求)构挤,使用異步方法(一調

用這個方法,它會自動開啟一個子線程去發(fā)送請求惕鼓,當請求成功筋现,數(shù)據(jù)返回的時候自動調用內(nèi)部的代碼段,這個代碼段在那個線程執(zhí)行取決于隊列箱歧,如果是主隊列矾飞,

那么在子線程發(fā)送請求成功拿到服務器的數(shù)據(jù)后,回到主線程中解析數(shù)據(jù)呀邢,刷新UI界面)洒沦。

B.使用代理方法發(fā)送異步請求

要監(jiān)聽服務器返回的data,所以使用協(xié)議

常見大代理方法如下:

1#pragmamark- NSURLConnectionDataDelegate代理方法23//當接收到服務器的響應(連通了服務器)時會調用45-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response67//當接收到服務器的數(shù)據(jù)時會調用(可能會被調用多次价淌,每次只傳遞部分數(shù)據(jù))89-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data1011//當服務器的數(shù)據(jù)加載完畢時就會調用1213-(void)connectionDidFinishLoading:(NSURLConnection *)connection1415//請求錯誤(失斏暄邸)的時候調用(請求超時\斷網(wǎng)\沒有網(wǎng)\瞒津,一般指客戶端錯誤)1617-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error

使用異步方法發(fā)送get請求的代碼示例:

1//2//YYViewController.m3//01-NSURLConnection的使用(GET)4//5//Created by apple on 14-6-28.6//Copyright (c) 2014年 itcase. All rights reserved.7//89#import"YYViewController.h"10#import"MBProgressHUD+MJ.h"1112@interfaceYYViewController ()13@property (weak, nonatomic) IBOutlet UITextField *username;14@property (weak, nonatomic) IBOutlet UITextField *pwd;15@property(nonatomic,strong)NSMutableData *responseData;16-(IBAction)login;1718@end1920@implementationYYViewController2122-(IBAction)login {23//1.提前的表單驗證24if(self.username.text.length==0) {25[MBProgressHUD showError:@"請輸入用戶名"];26return;27}28if(self.pwd.text.length==0) {29[MBProgressHUD showError:@"請輸入密碼"];30return;31}32//2.發(fā)送請求給服務器(帶上賬號和密碼)33//添加一個遮罩,禁止用戶操作34[MBProgressHUD showMessage:@"正在努力加載中...."];3536//37//2.1設置請求路徑38NSString *urlStr=[NSString stringWithFormat:@"http://192.168.1.53:8080/MJServer/login?username=%@&pwd=%@",self.username.text,self.pwd.text];39NSURL *url=[NSURL URLWithString:urlStr];4041//2.2創(chuàng)建請求對象42//NSURLRequest *request=[NSURLRequest requestWithURL:url];//默認就是GET請求43//設置請求超時44NSMutableURLRequest *request=[NSMutableURLRequest? requestWithURL:url];45request.timeoutInterval=5.0;4647//2.3.發(fā)送請求48//使用代理發(fā)送異步請求(通常應用于文件下載)49NSURLConnection *conn=[NSURLConnection connectionWithRequest:requestdelegate:self];50[conn start];51NSLog(@"已經(jīng)發(fā)出請求---");52}5354#pragmamark- NSURLConnectionDataDelegate代理方法55/*56*當接收到服務器的響應(連通了服務器)時會調用57*/58-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response59{60NSLog(@"接收到服務器的響應");61//初始化數(shù)據(jù)62self.responseData=[NSMutableData data];63}6465/*66*當接收到服務器的數(shù)據(jù)時會調用(可能會被調用多次括尸,每次只傳遞部分數(shù)據(jù))67*/68-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data69{70NSLog(@"接收到服務器的數(shù)據(jù)");71//拼接數(shù)據(jù)72[self.responseData appendData:data];73NSLog(@"%d---%@--",self.responseData.length,[NSThread currentThread]);74}7576/*77*當服務器的數(shù)據(jù)加載完畢時就會調用78*/79-(void)connectionDidFinishLoading:(NSURLConnection *)connection80{81NSLog(@"服務器的數(shù)據(jù)加載完畢");82//隱藏HUD83[MBProgressHUD hideHUD];8485//處理服務器返回的所有數(shù)據(jù)86NSDictionary *dict=[NSJSONSerialization JSONObjectWithData:self.responseData options:NSJSONReadingMutableLeaves error:nil];8788//判斷后巷蚪,在界面提示登錄信息89NSString *error=dict[@"error"];90if(error) {91[MBProgressHUD showError:error];92}else93{94NSString *success=dict[@"success"];95[MBProgressHUD showSuccess:success];96}97NSLog(@"%d---%@--",self.responseData.length,[NSThread currentThread]);98}99/*100*請求錯誤(失敗)的時候調用(請求超時\斷網(wǎng)\沒有網(wǎng)\濒翻,一般指客戶端錯誤)101*/102-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error103{104//NSLog(@"請求錯誤");105//隱藏HUD106[MBProgressHUD hideHUD];107[MBProgressHUD showError:@"網(wǎng)絡繁忙屁柏,請稍后重試!"];108}109@end

打印查看:

補充:

(1)數(shù)據(jù)的處理

在didReceiveData:方法中有送,拼接接收到的所有數(shù)據(jù)淌喻,等所有數(shù)據(jù)都拿到后,在connectionDidFinishLoading:方法中進行處理

(2)網(wǎng)絡延遲

在做網(wǎng)絡開發(fā)的時候雀摘,一定要考慮到網(wǎng)絡延遲情況的處理裸删,可以在服務器的代碼設置一個斷點模擬。

在服務器代碼的登錄方法中設置斷點

設置請求的最大延遲

模擬器情況:

打印查看:

三届宠、NSMutableURLRequest

NSMutableURLRequest是NSURLRequest的子類烁落,常用方法有

設置請求超時等待時間(超過這個時間就算超時,請求失斖阕ⅰ)- (void)setTimeoutInterval:(NSTimeInterval)seconds;

設置請求方法(比如GET和POST)- (void)setHTTPMethod:(NSString *)method;

設置請求體- (void)setHTTPBody:(NSData *)data;

設置請求頭- (void)setValue:(NSString *)value forHTTPHeaderField:(NSString *)field;

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末伤塌,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子轧铁,更是在濱河造成了極大的恐慌每聪,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,858評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件齿风,死亡現(xiàn)場離奇詭異药薯,居然都是意外死亡,警方通過查閱死者的電腦和手機救斑,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評論 3 395
  • 文/潘曉璐 我一進店門童本,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人脸候,你說我怎么就攤上這事穷娱。” “怎么了运沦?”我有些...
    開封第一講書人閱讀 165,282評論 0 356
  • 文/不壞的土叔 我叫張陵泵额,是天一觀的道長。 經(jīng)常有香客問我携添,道長嫁盲,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,842評論 1 295
  • 正文 為了忘掉前任烈掠,我火速辦了婚禮羞秤,結果婚禮上缸托,老公的妹妹穿的比我還像新娘。我一直安慰自己锥腻,他們只是感情好嗦董,可當我...
    茶點故事閱讀 67,857評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著瘦黑,像睡著了一般京革。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上幸斥,一...
    開封第一講書人閱讀 51,679評論 1 305
  • 那天匹摇,我揣著相機與錄音,去河邊找鬼甲葬。 笑死廊勃,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的经窖。 我是一名探鬼主播坡垫,決...
    沈念sama閱讀 40,406評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼画侣!你這毒婦竟也來了冰悠?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,311評論 0 276
  • 序言:老撾萬榮一對情侶失蹤配乱,失蹤者是張志新(化名)和其女友劉穎溉卓,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體搬泥,經(jīng)...
    沈念sama閱讀 45,767評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡桑寨,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了忿檩。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片尉尾。...
    茶點故事閱讀 40,090評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖燥透,靈堂內(nèi)的尸體忽然破棺而出代赁,到底是詐尸還是另有隱情,我是刑警寧澤兽掰,帶...
    沈念sama閱讀 35,785評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站徒役,受9級特大地震影響孽尽,放射性物質發(fā)生泄漏。R本人自食惡果不足惜忧勿,卻給世界環(huán)境...
    茶點故事閱讀 41,420評論 3 331
  • 文/蒙蒙 一杉女、第九天 我趴在偏房一處隱蔽的房頂上張望瞻讽。 院中可真熱鬧,春花似錦熏挎、人聲如沸速勇。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽烦磁。三九已至,卻和暖如春哼勇,著一層夾襖步出監(jiān)牢的瞬間都伪,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評論 1 271
  • 我被黑心中介騙來泰國打工积担, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留陨晶,地道東北人。 一個月前我還...
    沈念sama閱讀 48,298評論 3 372
  • 正文 我出身青樓帝璧,卻偏偏與公主長得像先誉,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子的烁,可洞房花燭夜當晚...
    茶點故事閱讀 45,033評論 2 355

推薦閱讀更多精彩內(nèi)容