欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

iOS開發(fā)中使用NSURLConnection類處理網(wǎng)絡(luò)請(qǐng)求的方法

 更新時(shí)間:2015年12月27日 10:03:06   作者:文頂頂  
這篇文章主要介紹了iOS開發(fā)中使用NSURLConnection類處理網(wǎng)絡(luò)請(qǐng)求的方法,代碼基于傳統(tǒng)的Objective-C,需要的朋友可以參考下

NSURLConnection 作為 Core Foundation / CFNetwork 框架的 API 之上的一個(gè)抽象,在 2003 年,隨著第一版的 Safari 的發(fā)布就發(fā)布了。NSURLConnection 這個(gè)名字,實(shí)際上是指代的 Foundation 框架的 URL 加載系統(tǒng)中一系列有關(guān)聯(lián)的組件:NSURLRequest、NSURLResponse、NSURLProtocol、 NSURLCache、 NSHTTPCookieStorage、NSURLCredentialStorage 以及同名類 NSURLConnection。

NSURLRequest 被傳遞給 NSURLConnection。被委托對(duì)象(遵守以前的非正式協(xié)議 <NSURLConnectionDelegate> 和 <NSURLConnectionDataDelegate>)異步地返回一個(gè) NSURLResponse 以及包含服務(wù)器返回信息的 NSData。

在一個(gè)請(qǐng)求被發(fā)送到服務(wù)器之前,系統(tǒng)會(huì)先查詢共享的緩存信息,然后根據(jù)策略(policy)以及可用性(availability)的不同,一個(gè)已經(jīng)被緩存的響應(yīng)可能會(huì)被立即返回。如果沒有緩存的響應(yīng)可用,則這個(gè)請(qǐng)求將根據(jù)我們指定的策略來緩存它的響應(yīng)以便將來的請(qǐng)求可以使用。

在把請(qǐng)求發(fā)送給服務(wù)器的過程中,服務(wù)器可能會(huì)發(fā)出鑒權(quán)查詢(authentication challenge),這可以由共享的 cookie 或機(jī)密存儲(chǔ)(credential storage)來自動(dòng)響應(yīng),或者由被委托對(duì)象來響應(yīng)。發(fā)送中的請(qǐng)求也可以被注冊(cè)的 NSURLProtocol 對(duì)象所攔截,以便在必要的時(shí)候無縫地改變其加載行為。

不管怎樣,NSURLConnection 作為網(wǎng)絡(luò)基礎(chǔ)架構(gòu),已經(jīng)服務(wù)了成千上萬的 iOS 和 Mac OS 程序,并且做的還算相當(dāng)不錯(cuò)。但是這些年,一些用例——尤其是在 iPhone 和 iPad 上面——已經(jīng)對(duì) NSURLConnection 的幾個(gè)核心概念提出了挑戰(zhàn),讓蘋果有理由對(duì)它進(jìn)行重構(gòu)。

一、NSURLConnection的常用類

(1)NSURL:請(qǐng)求地址

(2)NSURLRequest:封裝一個(gè)請(qǐng)求,保存發(fā)給服務(wù)器的全部數(shù)據(jù),包括一個(gè)NSURL對(duì)象,請(qǐng)求方法、請(qǐng)求頭、請(qǐng)求體....

(3)NSMutableURLRequest:NSURLRequest的子類

(4)NSURLConnection:負(fù)責(zé)發(fā)送請(qǐng)求,建立客戶端和服務(wù)器的連接。發(fā)送NSURLRequest的數(shù)據(jù)給服務(wù)器,并收集來自服務(wù)器的響應(yīng)數(shù)據(jù)

 

二、NSURLConnection的使用
1.簡單說明
使用NSURLConnection發(fā)送請(qǐng)求的步驟很簡單

(1)創(chuàng)建一個(gè)NSURL對(duì)象,設(shè)置請(qǐng)求路徑(設(shè)置請(qǐng)求路徑)

(2)傳入NSURL創(chuàng)建一個(gè)NSURLRequest對(duì)象,設(shè)置請(qǐng)求頭和請(qǐng)求體(創(chuàng)建請(qǐng)求對(duì)象)

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

2015122795428844.png (711×228)

2.代碼示例

(1)發(fā)送請(qǐng)求的三個(gè)步驟:

1.設(shè)置請(qǐng)求路徑
2.創(chuàng)建請(qǐng)求對(duì)象
3.發(fā)送請(qǐng)求
3.1發(fā)送同步請(qǐng)求(一直在等待服務(wù)器返回?cái)?shù)據(jù),這行代碼會(huì)卡住,如果服務(wù)器,沒有返回?cái)?shù)據(jù),那么在主線程UI會(huì)卡住不能繼續(xù)執(zhí)行操作)有返回值
3.2發(fā)送異步請(qǐng)求:沒有返回值
說明:任何NSURLRequest默認(rèn)都是get請(qǐng)求。
 
(2)發(fā)送同步請(qǐng)求代碼示例:

復(fù)制代碼 代碼如下:

//
//  YYViewController.m
//  01-NSURLConnection的使用(GET)
//
//  Created by apple on 14-6-28.
//  Copyright (c) 2014年 itcase. All rights reserved.
//

#import "YYViewController.h"
#import "MBProgressHUD+MJ.h"

@interface YYViewController ()
@property (weak, nonatomic) IBOutlet UITextField *username;
@property (weak, nonatomic) IBOutlet UITextField *pwd;
- (IBAction)login;

@end


復(fù)制代碼 代碼如下:

@implementation YYViewController

- (IBAction)login {
//    1.提前的表單驗(yàn)證
    if (self.username.text.length==0) {
        [MBProgressHUD showError:@"請(qǐng)輸入用戶名"];
        return;
    }
    if (self.pwd.text.length==0) {
        [MBProgressHUD showError:@"請(qǐng)輸入密碼"];
        return;
    }
//    2.發(fā)送請(qǐng)求給服務(wù)器(帶上賬號(hào)和密碼)
    //添加一個(gè)遮罩,禁止用戶操作
//    [MBProgressHUD showMessage:@"正在努力加載中...."];
//    GET請(qǐng)求:請(qǐng)求行\(zhòng)請(qǐng)求頭\請(qǐng)求體
//
//    1.設(shè)置請(qǐng)求路徑
    NSString *urlStr=[NSString stringWithFormat:@"http://192.168.1.53:8080/MJServer/login?username=%@&pwd=%@",self.username.text,self.pwd.text];
    NSURL *url=[NSURL URLWithString:urlStr];
//    2.創(chuàng)建請(qǐng)求對(duì)象
    NSURLRequest *request=[NSURLRequest requestWithURL:url];
//    3.發(fā)送請(qǐng)求
    //發(fā)送同步請(qǐng)求,在主線程執(zhí)行
    NSData *data=[NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
    //(一直在等待服務(wù)器返回?cái)?shù)據(jù),這行代碼會(huì)卡住,如果服務(wù)器沒有返回?cái)?shù)據(jù),那么在主線程UI會(huì)卡住不能繼續(xù)執(zhí)行操作)
    NSLog(@"--%d--",data.length);
}
@end


模擬器情況:

2015122795506580.png (319×500)

打印服務(wù)器返回的信息:

2015122795525160.png (965×41)

補(bǔ)充說明:
1.提前的表單驗(yàn)證
2.發(fā)送請(qǐng)求給服務(wù)器(帶上賬號(hào)和密碼)
GET請(qǐng)求:請(qǐng)求行\(zhòng)請(qǐng)求頭\請(qǐng)求體
注意:GET請(qǐng)求中不存在請(qǐng)求體,因?yàn)樗械男畔⒍紝懺赨RL里面。在IOS里面,請(qǐng)求行和請(qǐng)求頭都不用寫。
 
(3)發(fā)送異步請(qǐng)求
發(fā)送異步請(qǐng)求有兩種方式:
1)使用block回調(diào)
2)代理
A.使用block回調(diào)方法發(fā)送異步請(qǐng)求
使用block回調(diào)代碼示例:

復(fù)制代碼 代碼如下:

//
//  YYViewController.m
//  01-NSURLConnection的使用(GET)
//
//  Created by apple on 14-6-28.
//  Copyright (c) 2014年 itcase. All rights reserved.
//

#import "YYViewController.h"
#import "MBProgressHUD+MJ.h"

@interface YYViewController ()
@property (weak, nonatomic) IBOutlet UITextField *username;
@property (weak, nonatomic) IBOutlet UITextField *pwd;
- (IBAction)login;

@end


復(fù)制代碼 代碼如下:

@implementation YYViewController

- (IBAction)login {
//    1.提前的表單驗(yàn)證
    if (self.username.text.length==0) {
        [MBProgressHUD showError:@"請(qǐng)輸入用戶名"];
        return;
    }
    if (self.pwd.text.length==0) {
        [MBProgressHUD showError:@"請(qǐng)輸入密碼"];
        return;
    }
//    2.發(fā)送請(qǐng)求給服務(wù)器(帶上賬號(hào)和密碼)
    //添加一個(gè)遮罩,禁止用戶操作
    [MBProgressHUD showMessage:@"正在努力加載中...."];

//
//    1.設(shè)置請(qǐng)求路徑
    NSString *urlStr=[NSString stringWithFormat:@"http://192.168.1.53:8080/MJServer/login?username=%@&pwd=%@",self.username.text,self.pwd.text];
    NSURL *url=[NSURL URLWithString:urlStr];
   
//    2.創(chuàng)建請(qǐng)求對(duì)象
    NSURLRequest *request=[NSURLRequest requestWithURL:url];
   
//    3.發(fā)送請(qǐng)求
    //3.1發(fā)送同步請(qǐng)求,在主線程執(zhí)行
//    NSData *data=[NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
    //(一直在等待服務(wù)器返回?cái)?shù)據(jù),這行代碼會(huì)卡住,如果服務(wù)器沒有返回?cái)?shù)據(jù),那么在主線程UI會(huì)卡住不能繼續(xù)執(zhí)行操作)
   
    //3.1發(fā)送異步請(qǐng)求
    //創(chuàng)建一個(gè)隊(duì)列(默認(rèn)添加到該隊(duì)列中的任務(wù)異步執(zhí)行)
//    NSOperationQueue *queue=[[NSOperationQueue alloc]init];
    //獲取一個(gè)主隊(duì)列
    NSOperationQueue *queue=[NSOperationQueue mainQueue];
    [NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
        NSLog(@"--block回調(diào)數(shù)據(jù)--%@---%d", [NSThread currentThread],data.length);
        //隱藏HUD,刷新UI的操作一定要放在主線程執(zhí)行
        [MBProgressHUD hideHUD];
       
        //解析data
        /*
        {"success":"登錄成功"}
        {"error":"用戶名不存在"}
        {"error":"密碼不正確"}
         */
        NSDictionary *dict=[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil];
        NSLog(@"%@",dict);
       
        //判斷后,在界面提示登錄信息
        NSString *error=dict[@"error"];
        if (error) {
            [MBProgressHUD showError:error];
        }else
        {
            NSString *success=dict[@"success"];
            [MBProgressHUD showSuccess:success];
        }
    }];
    NSLog(@"請(qǐng)求發(fā)送完畢");
}
@end


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

2015122795603843.png (640×960)

打印查看:

20151227100255079.png (1104×129)

代碼說明:
block代碼段:當(dāng)服務(wù)器有返回?cái)?shù)據(jù)的時(shí)候調(diào)用會(huì)開一條新的線程去發(fā)送請(qǐng)求,主線程繼續(xù)往下走,當(dāng)拿到服務(wù)器的返回?cái)?shù)據(jù)的數(shù)據(jù)的時(shí)候再回調(diào)block,執(zhí)行block代碼段。這種情況不會(huì)卡住主線程。
隊(duì)列的作用:決定這個(gè)block操作放在哪個(gè)線程執(zhí)行?
刷新UI界面的操作應(yīng)該放在主線程執(zhí)行,不能放在子線程,在子線程處理UI相關(guān)操作會(huì)出現(xiàn)一些莫名的問題。
提示:
(1)創(chuàng)建一個(gè)操作,放在NSOperation隊(duì)列中執(zhí)行,默認(rèn)是異步執(zhí)行的。
(2)mainqueue   返回一個(gè)和主線程相關(guān)的隊(duì)列,即主隊(duì)列。
 
新的問題:如果向服務(wù)器發(fā)送請(qǐng)求,卻并沒有拿到數(shù)據(jù),那么程序會(huì)崩潰(data不能為空)
改進(jìn)代碼:

復(fù)制代碼 代碼如下:

NSOperationQueue *queue=[NSOperationQueue mainQueue];
    [NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
        //當(dāng)請(qǐng)求結(jié)束的時(shí)候調(diào)用(有兩種結(jié)果,一個(gè)是成功拿到數(shù)據(jù),也可能沒有拿到數(shù)據(jù),請(qǐng)求失?。?br />         NSLog(@"--block回調(diào)數(shù)據(jù)--%@---%d", [NSThread currentThread],data.length);
        //隱藏HUD,刷新UI的操作一定要放在主線程執(zhí)行
        [MBProgressHUD hideHUD];
       
        //解析data
        /*
        {"success":"登錄成功"}
        {"error":"用戶名不存在"}
        {"error":"密碼不正確"}
         */
        if (data) {//請(qǐng)求成功
            NSDictionary *dict=[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil];
            NSLog(@"%@",dict);
           
            //判斷后,在界面提示登錄信息
            NSString *error=dict[@"error"];
            if (error) {
                [MBProgressHUD showError:error];
            }else
            {
                NSString *success=dict[@"success"];
                [MBProgressHUD showSuccess:success];
            }
        }else   //請(qǐng)求失敗
        {
            [MBProgressHUD showError:@"網(wǎng)絡(luò)繁忙,請(qǐng)稍后重試!"];
        }
    
    }];

解析data
復(fù)制代碼 代碼如下:

   //解析data
        /*
        {"success":"登錄成功"}
        {"error":"用戶名不存在"}
        {"error":"密碼不正確"}
         */

說明:使用NSJSONSerialization 返回的對(duì)象,取決于最外層是什么,如果是{}那就是字典,[]那就是數(shù)組等。
補(bǔ)充說明:
首先確定請(qǐng)求路徑,然后創(chuàng)建請(qǐng)求對(duì)象(默認(rèn)發(fā)送的時(shí)get請(qǐng)求),使用異步方法(一調(diào)用這個(gè)方法,它會(huì)自動(dòng)開啟一個(gè)子線程去發(fā)送請(qǐng)求,當(dāng)請(qǐng)求成功,數(shù)據(jù)返回的時(shí)候自動(dòng)調(diào)用內(nèi)部的代碼段,這個(gè)代碼段在那個(gè)線程執(zhí)行取決于隊(duì)列,如果是主隊(duì)列,那么在子線程發(fā)送請(qǐng)求成功拿到服務(wù)器的數(shù)據(jù)后,回到主線程中解析數(shù)據(jù),刷新UI界面)。
 
B.使用代理方法發(fā)送異步請(qǐng)求
要監(jiān)聽服務(wù)器返回的data,所以使用<NSURLConnectionDataDelegate>協(xié)議

常見大代理方法如下:

復(fù)制代碼 代碼如下:

#pragma mark- NSURLConnectionDataDelegate代理方法

//當(dāng)接收到服務(wù)器的響應(yīng)(連通了服務(wù)器)時(shí)會(huì)調(diào)用

-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response

//當(dāng)接收到服務(wù)器的數(shù)據(jù)時(shí)會(huì)調(diào)用(可能會(huì)被調(diào)用多次,每次只傳遞部分?jǐn)?shù)據(jù))

-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data

//當(dāng)服務(wù)器的數(shù)據(jù)加載完畢時(shí)就會(huì)調(diào)用

-(void)connectionDidFinishLoading:(NSURLConnection *)connection

//請(qǐng)求錯(cuò)誤(失?。┑臅r(shí)候調(diào)用(請(qǐng)求超時(shí)\斷網(wǎng)\沒有網(wǎng)\,一般指客戶端錯(cuò)誤)

-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error


使用異步方法發(fā)送get請(qǐng)求的代碼示例:
復(fù)制代碼 代碼如下:

//
//  YYViewController.m
//  01-NSURLConnection的使用(GET)
//
//  Created by apple on 14-6-28.
//  Copyright (c) 2014年 itcase. All rights reserved.
//

#import "YYViewController.h"
#import "MBProgressHUD+MJ.h"

@interface YYViewController ()<NSURLConnectionDataDelegate>
@property (weak, nonatomic) IBOutlet UITextField *username;
@property (weak, nonatomic) IBOutlet UITextField *pwd;
@property(nonatomic,strong)NSMutableData *responseData;
- (IBAction)login;

@end


復(fù)制代碼 代碼如下:

@implementation YYViewController

- (IBAction)login {
//    1.提前的表單驗(yàn)證
    if (self.username.text.length==0) {
        [MBProgressHUD showError:@"請(qǐng)輸入用戶名"];
        return;
    }
    if (self.pwd.text.length==0) {
        [MBProgressHUD showError:@"請(qǐng)輸入密碼"];
        return;
    }
//    2.發(fā)送請(qǐng)求給服務(wù)器(帶上賬號(hào)和密碼)
    //添加一個(gè)遮罩,禁止用戶操作
    [MBProgressHUD showMessage:@"正在努力加載中...."];

//
//   2.1設(shè)置請(qǐng)求路徑
    NSString *urlStr=[NSString stringWithFormat:@"http://192.168.1.53:8080/MJServer/login?username=%@&pwd=%@",self.username.text,self.pwd.text];
    NSURL *url=[NSURL URLWithString:urlStr];
   
//   2.2創(chuàng)建請(qǐng)求對(duì)象
//    NSURLRequest *request=[NSURLRequest requestWithURL:url];//默認(rèn)就是GET請(qǐng)求
    //設(shè)置請(qǐng)求超時(shí)
    NSMutableURLRequest *request=[NSMutableURLRequest  requestWithURL:url];
    request.timeoutInterval=5.0;
   
//   2.3.發(fā)送請(qǐng)求
 //使用代理發(fā)送異步請(qǐng)求(通常應(yīng)用于文件下載)
    NSURLConnection *conn=[NSURLConnection connectionWithRequest:request delegate:self];
    [conn start];
    NSLog(@"已經(jīng)發(fā)出請(qǐng)求---");
}

#pragma mark- NSURLConnectionDataDelegate代理方法
/*
 *當(dāng)接收到服務(wù)器的響應(yīng)(連通了服務(wù)器)時(shí)會(huì)調(diào)用
 */
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
    NSLog(@"接收到服務(wù)器的響應(yīng)");
    //初始化數(shù)據(jù)
    self.responseData=[NSMutableData data];
}

/*
*當(dāng)接收到服務(wù)器的數(shù)據(jù)時(shí)會(huì)調(diào)用(可能會(huì)被調(diào)用多次,每次只傳遞部分?jǐn)?shù)據(jù))
*/
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    NSLog(@"接收到服務(wù)器的數(shù)據(jù)");
    //拼接數(shù)據(jù)
    [self.responseData appendData:data];
        NSLog(@"%d---%@--",self.responseData.length,[NSThread currentThread]);
}

/*
 *當(dāng)服務(wù)器的數(shù)據(jù)加載完畢時(shí)就會(huì)調(diào)用
 */
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    NSLog(@"服務(wù)器的數(shù)據(jù)加載完畢");
    //隱藏HUD
    [MBProgressHUD hideHUD];
   
    //處理服務(wù)器返回的所有數(shù)據(jù)
    NSDictionary *dict=[NSJSONSerialization JSONObjectWithData:self.responseData options:NSJSONReadingMutableLeaves error:nil];
   
    //判斷后,在界面提示登錄信息
    NSString *error=dict[@"error"];
    if (error) {
        [MBProgressHUD showError:error];
    }else
    {
        NSString *success=dict[@"success"];
        [MBProgressHUD showSuccess:success];
    }
    NSLog(@"%d---%@--",self.responseData.length,[NSThread currentThread]);
}
/*
 *請(qǐng)求錯(cuò)誤(失?。┑臅r(shí)候調(diào)用(請(qǐng)求超時(shí)\斷網(wǎng)\沒有網(wǎng)\,一般指客戶端錯(cuò)誤)
 */
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
//     NSLog(@"請(qǐng)求錯(cuò)誤");
    //隱藏HUD
    [MBProgressHUD hideHUD];
    [MBProgressHUD showError:@"網(wǎng)絡(luò)繁忙,請(qǐng)稍后重試!"];
}
@end


打印查看:

20151227100022464.png (854×124)

補(bǔ)充:

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

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

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

在做網(wǎng)絡(luò)開發(fā)的時(shí)候,一定要考慮到網(wǎng)絡(luò)延遲情況的處理,可以在服務(wù)器的代碼設(shè)置一個(gè)斷點(diǎn)模擬。

在服務(wù)器代碼的登錄方法中設(shè)置斷點(diǎn)

2015122795703957.png (587×396)

設(shè)置請(qǐng)求的最大延遲

2015122795721732.png (895×154)

模擬器情況:

2015122795903439.png (640×960)

打印查看:

2015122795755620.png (928×85)

三、NSMutableURLRequest

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

設(shè)置請(qǐng)求超時(shí)等待時(shí)間(超過這個(gè)時(shí)間就算超時(shí),請(qǐng)求失?。?div id="vvxyksv9kd" class="codetitle">復(fù)制代碼 代碼如下:

- (void)setTimeoutInterval:(NSTimeInterval)seconds;

設(shè)置請(qǐng)求方法(比如GET和POST)

復(fù)制代碼 代碼如下:
- (void)setHTTPMethod:(NSString *)method;

設(shè)置請(qǐng)求體

復(fù)制代碼 代碼如下:
- (void)setHTTPBody:(NSData *)data;

設(shè)置請(qǐng)求頭

復(fù)制代碼 代碼如下:
- (void)setValue:(NSString *)value forHTTPHeaderField:(NSString *)field;

相關(guān)文章

最新評(píng)論