【iOS出租屋進階】之網(wǎng)絡(luò)通信

HTTP協(xié)議POST、GET

訪問網(wǎng)絡(luò)數(shù)據(jù)大部分都要用到HTTP協(xié)議,通過HTTP協(xié)議向服務(wù)器請求數(shù)據(jù),再通過HTTP協(xié)議獲得服務(wù)器的響應(yīng)數(shù)據(jù),常見的操作主要是POST與GET,這兩個操作可以滿足絕大部分的應(yīng)用需求了。
GET操作主要使用場景是請求網(wǎng)絡(luò)資源,例如在瀏覽器中訪問網(wǎng)頁就發(fā)起了很多GET請求,GET請求的缺點在于安全性不夠,參數(shù)都在URL中了,并且不同的瀏覽器對URL長度有不同長度的限制,一些復(fù)雜的請求就不適用了。這時候需要用POST請求,POST請求的所有參數(shù)都放在請求體中,安全性更好,并且理論上沒有數(shù)據(jù)量的限制,文件上傳、賬號登陸等都用POST請求。 一般GET請求只適合于簡單的查詢請求,增刪改一般都用POST請求。

簡單的網(wǎng)絡(luò)請求 dataWithContentsOfURL

NSURL *url = [NSURL URLWithString:@"http://upload-images.jianshu.io/upload_images/1634654-d8b4a14ae77aa685.jpg"];
NSData *data = [NSData dataWithContentsOfURL:url];

NSURLConnection 基本使用

同步請求
 //    1.設(shè)置請求路徑
 NSURL *url=[NSURL URLWithString:@"http://upload-images.jianshu.io/upload_images/1634654-d8b4a14ae77aa685.jpg"];
 //    2.創(chuàng)建請求對象 **(任何NSURLRequest默認都是GET請求)**
 NSURLRequest *request=[NSURLRequest requestWithURL:url];
 //    3.發(fā)送請求
 //    發(fā)送同步請求,在主線程執(zhí)行
 NSData *data=[NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
//(一直在等待服務(wù)器返回數(shù)據(jù),這行代碼會卡住,如果服務(wù)器沒有返回數(shù)據(jù),那么在主線程UI會卡住不能繼續(xù)執(zhí)行操作)

異步請求

發(fā)送異步請求有兩種方式:使用block回調(diào)和代理
首先確定請求路徑,然后創(chuàng)建請求對象(默認發(fā)送的時GET請求),使用異步方法(一調(diào)用這個方法,它會自動開啟一個子線程去發(fā)送請求,當(dāng)請求成功,數(shù)據(jù)返回的時候自動調(diào)用內(nèi)部的代碼段,這個代碼段在那個線程執(zhí)行取決于隊列,如果是主隊列,那么在子線程發(fā)送請求成功拿到服務(wù)器的數(shù)據(jù)后,回到主線程中解析數(shù)據(jù),刷新UI界面)

 //    1.設(shè)置請求路徑
 NSURL *url=[NSURL URLWithString:@"http://upload-images.jianshu.io/upload_images/1634654-d8b4a14ae77aa685.jpg"];
 //    2.創(chuàng)建請求對象 **(任何NSURLRequest默認都是GET請求)**
 NSURLRequest *request=[NSURLRequest requestWithURL:url];
 //    3.獲取一個主隊列
 NSOperationQueue *queue=[NSOperationQueue mainQueue];
 [NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
         //當(dāng)請求結(jié)束的時候調(diào)用(有兩種結(jié)果,一個是成功拿到數(shù)據(jù),也可能沒有拿到數(shù)據(jù),請求失?。?         if (data) {//請求成功
             NSDictionary *dict=[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil];
             NSLog(@"%@",dict);
         }else {  //請求失敗
             NSLog(@"請求失敗");
         }   
     }];

使用代理發(fā)送異步請求

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

//當(dāng)接收到服務(wù)器的響應(yīng)(連通了服務(wù)器)時會調(diào)用
 - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response 
//當(dāng)接收到服務(wù)器的數(shù)據(jù)時會調(diào)用(可能會被調(diào)用多次,每次只傳遞部分數(shù)據(jù))
 - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
//當(dāng)服務(wù)器的數(shù)據(jù)加載完畢時就會調(diào)用
 - (void)connectionDidFinishLoading:(NSURLConnection *)connection
//請求錯誤(失敗)的時候調(diào)用(請求超時\斷網(wǎng)\沒有網(wǎng)\,一般指客戶端錯誤)
 - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error 
發(fā)送請求

NSMutableURLRequestNSURLRequest 的子類,常用方法有

設(shè)置請求超時等待時間(超過這個時間就算超時,請求失?。? (void)setTimeoutInterval:(NSTimeInterval)seconds;
設(shè)置請求方法(比如GET和POST)- (void)setHTTPMethod:(NSString *)method;
設(shè)置請求體 - (void)setHTTPBody:(NSData *)data;
設(shè)置請求頭 - (void)setValue:(NSString *)value forHTTPHeaderField:(NSString *)field;
 //    1.設(shè)置請求路徑
 NSURL *url=[NSURL URLWithString:@"http://upload-images.jianshu.io/upload_images/1634654-d8b4a14ae77aa685.jpg"];
 //    2.創(chuàng)建請求對象 **(任何NSURLRequest默認都是GET請求)**
 NSMutableURLRequest  *request=[NSURLRequest requestWithURL:url];
 //    設(shè)置請求超時
 request.timeoutInterval=5.0;
 //    .3.發(fā)送請求
 //使用代理發(fā)送異步請求(通常應(yīng)用于文件下載)
 NSURLConnection *conn=[NSURLConnection connectionWithRequest:request delegate:self];
 [conn start];

NSURLSession

NSURLConnection,在iOS 9被宣布棄用,取而代之是NSURLSession的崛起

 //**GET請求**
 //    1.設(shè)置請求路徑
 NSURL *url=[NSURL URLWithString:@"http://upload-images.jianshu.io/upload_images/1634654-d8b4a14ae77aa685.jpg"];
 //    2.創(chuàng)建請求對象 **(任何NSURLRequest默認都是GET請求)**
 NSURLRequest *request=[NSURLRequest requestWithURL:url];
 //    3.獲取會話的對象
 NSURLSession *session = [NSURLSession sharedSession];
 //    4.根據(jù)會話對象,創(chuàng)建一個Task任務(wù)
 NSURLSessionDataTask *sessionDataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
         //對從服務(wù)器獲取到的數(shù)據(jù)data進行相應(yīng)的處理
        NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:(NSJSONReadingMutableLeaves) error:nil];
    }];
 //    5.執(zhí)行任務(wù)
 [sessionDataTask resume];



 //**POST請求**,POST和GET的區(qū)別就在于request,所以使用session的POST請求和GET過程是一樣的,區(qū)別就在于對request的處理
 //    1.設(shè)置請求路徑
 NSURL *url=[NSURL URLWithString:@"http://upload-images.jianshu.io/upload_images/1634654-d8b4a14ae77aa685.jpg"];
 //    2.創(chuàng)建請求對象,設(shè)置請求方法、請求參數(shù)
 NSURLRequest *request=[NSURLRequest requestWithURL:url];
 request.HTTPMethod = @"POST";
 request.HTTPBody = [@"username=xx&pwd=xx" dataUsingEncoding:NSUTF8StringEncoding];
 //    3.獲取會話的對象
 NSURLSession *session = [NSURLSession sharedSession];
 //    4.根據(jù)會話對象,創(chuàng)建一個Task任務(wù)
 NSURLSessionDataTask *sessionDataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
         //對從服務(wù)器獲取到的數(shù)據(jù)data進行相應(yīng)的處理
        NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:(NSJSONReadingMutableLeaves) error:nil];
    }];
 //    5.執(zhí)行任務(wù)
 [sessionDataTask resume];

NSURLSessionDataDelegate代理方法

NSURLSession提供了block方式處理返回數(shù)據(jù)的簡便方式,但如果想要在接收數(shù)據(jù)過程中做進一步的處理,仍然可以調(diào)用相關(guān)的協(xié)議方法.NSURLSession的代理方法和NSURLConnection有些類似,都是分為接收響應(yīng)、接收數(shù)據(jù)、請求完成幾個階段

// 使用代理方法需要設(shè)置代理,但是session的delegate屬性是只讀的,要想設(shè)置代理只能通過這種方式創(chuàng)建session
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[[NSOperationQueue alloc] init]];
// 創(chuàng)建任務(wù)(因為要使用代理方法,就不需要block方式的初始化了)
NSURLSessionDataTask *task = [session dataTaskWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.daka.com/login?userName=daka&pwd=123"]]];
// 啟動任務(wù)
[task resume];

// 1.接收到服務(wù)器的響應(yīng)
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler {
    // 允許處理服務(wù)器的響應(yīng),才會繼續(xù)接收服務(wù)器返回的數(shù)據(jù)
    completionHandler(NSURLSessionResponseAllow);
}
// 2.接收到服務(wù)器的數(shù)據(jù)(可能調(diào)用多次)
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data {
    // 處理每次接收的數(shù)據(jù)
}
// 3.請求成功或者失敗(如果失敗,error有值)
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
    // 請求完成,成功或者失敗的處理
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容