iOS中的網路--NSURLConnection

weixin_33976072發表於2015-09-30

URL:Uniform Resource Locator(統一資源定位符) 通過URL能找到唯一的1個資源
URL的格式: 協議://主機地址/路徑

協議:不同的協議,代表不同的資源查詢方式,資源傳輸方式:
http://超文字傳輸協議(遠端網路資源)
file://本地計算機上的資源
ftp://共享主機的檔案資源
主機地址:存放資源的主機(伺服器)的IP地址(域名)
路徑: 資源在主機(伺服器)中的具體為準

692194-35ad3db1fd3c72d1.png
Snip20150930_12.png

1.常見傳送HTTP請求的請求方法:
增:PUT 刪:DELETE 改:POST 查:GET
目前最常用的就是GET和POST

GET和POST的對比

主要區別表現在資料傳遞上
GET:
1.請求URL後面以?的形式更上傳遞給伺服器的引數,當有多個引數時用&隔開,比如:http://ww.test.com/login?username=123&pwd=234&type=JSON
引數是什麼就傳什麼, 不要隨意新增等號.
2.由於瀏覽器和伺服器對URL長度有限制,因此在URL後面附帶的引數是有限制的.通常不超過1KB. 當然這種請求也是不安全的. 因為引數都暴露在外邊,對使用者來說是及其不安全的.
POST:
1.傳送給伺服器的引數全部放在了請求體
2.POST傳遞的資料量是沒有限制的(具體看伺服器的處理能力)

GET和POST的選擇

1.如果傳遞大量資料,比如檔案上傳,只能POST請求
2.GET的安全性比POST差,包含機密資訊的,建議是有POST
3.如果僅僅是索取資料(資料查詢),建議使用GET
4.如果是其他操作建議使用 POST

iOS中傳送HTTP請求的方案

1.蘋果原生(自帶)
1>NSURLConnection:(IOS7以前)用法簡單,最古老最經典最直接的一種方法,用法簡單,但是坑比較多
2>NSURLSession:功能比NSURLConnection更加強大,蘋果比較推薦使用的技術[iOS7推出]
3>CFNetwork:NSURL的底層,純C語言.
2.三方框架
AFNetworking:簡單易用,維護者比較多

HTTP通訊過程 - 請求

HTTP協議規定:包含請求頭---請求體
請求頭:包含了對客戶端 的環境描述,客戶端請求資訊等
(這個和伺服器有關)


692194-16d297498218e8ef.png
Snip20150930_14.png

這是從網頁上擷取的資料, 上半部分是響應頭,下半部分為請求頭
請求體:客戶端發給伺服器的具體資料,比如檔案資料(POST請求才會有)

HTTP通訊過程 - 響應

客戶端想伺服器傳送請求,伺服器應當做出響應,即返回資料給客戶端
HTTP響應包含:響應頭,響應體


692194-8665155c7783bc41.png
Snip20150930_15.png

NSURLConnection

使用比較簡單,

常見類(學習一個類,就要先看裡面的屬性,和方法)
1.NSURL:請求地址
2.NSURLRequest:一個NSURLRequest物件就代表一個請求,它包含資訊有請求方法,請求頭,請求體,請求超時等....
3.NSMutableURLRequest:NSURLRequest的子類
4.NSURLConnection
1>負責傳送請求,建立客戶端和伺服器的連結
2>傳送資料給伺服器,並收集來自伺服器的響應資料

使用步驟

1.使用NSURLConnection傳送請求的步驟很簡單
1> 建立一個NSURL物件,設定請求路徑
2> 傳入NSURL建立一個NSURLRequest/NSMutableURLRequest物件,設定請求頭和請求體
3> 使用NSURLConnection傳送請求

692194-ddc120c36061f886.png
Snip20150930_16.png

#######傳送請求的幾種方式
1.同步請求(從古至今都不常用)
+ (NSData *)sendSynchronousRequest:(NSURLRequest *)request returningResponse:(NSURLResponse **)response error:(NSError **)error
傳送一個請求,返回一個NSDate資料,

  // Get 操作
    // http:// 協議頭
    // 120.25.226.186:32812/login 路徑
    // 以?區分,後面是發給伺服器的引數,以&區分
    // get 會在url中暴露使用者的隱私。所以一般用於小資料,不重要的資料請求。
    NSString *urlStr = @"http://120.25.226.186:32812/login?username=520it&pwd=520it&type=JSON";
    NSURL *url = [NSURL URLWithString:urlStr];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    NSURLResponse *response = [[NSURLResponse alloc]init];
    // 傳送請求 ,返回請求得到的資料。
    // 第一個引數:傳送的請求
    // 當伺服器返回資料後,就會將 得到的資料<響應頭>,賦值給 響應中
    // 同步傳送請求,  會阻塞執行緒,一般不使用
    NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil ];
    NSString *str = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
    NSLog(@"%@----%@",str,response);
    NSLog(@"我愛你");

2.非同步請求:根據對伺服器返回資料的處理方式的不同,又可以分為以下2種
1> block回撥
+(void)sendAsynchronousRequest:(NSURLRequest*) request queue:(NSOperationQueue*) queue completionHandler:(void (^)(NSURLResponse* response,NSData* data, NSError* connectionError)) handler;

NSString *urlStr = @"http://120.25.226.186:32812/login?username=520it&pwd=520it&type=JSON";
    
    NSURL *url = [NSURL URLWithString:urlStr];
    
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    
    /*
     傳送非同步請求, 不會阻塞主執行緒。效率能提高。
     第一個引數:傳送的什麼非同步請求
     第二個引數:回撥在哪一個佇列(一般傳主佇列)
     第三個引數有:block 可接受到,響應資料,響應頭,以及響應狀態(錯誤值)
     */
    [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
        NSString *dataStr = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
        NSLog(@"%@",dataStr);
    }];
    NSLog(@"ლ(′◉❥◉`ლ)");

2>代理髮送非同步請求
// 物件方法,建立連線直接傳送請求(資料在代理中)
- (id)initWithRequest:(NSURLRequest *)request delegate:(id)delegate

+ (NSURLConnection *)connectionWithRequest:(NSURLRequest *)request delegate:(id)delegate

- (id)initWithRequest:(NSURLRequest *)request delegate:(id)delegate startImmediately:(BOOL)startImmediately

**在startImmediately = NO的情況下, 需要呼叫start方法開始傳送請求
- (void)start
實現代理時, 遵循代理方法NSURLConnectionDataDelegate

NSMutableURLRequest (POST)

繼承於NSURLRequest (GET預設,不可換)
在NSMutableURLRequest中可以設定請求方式(HTTPMethod),設定請求內容(HTTPBody),修改和增加請求頭內容,(KVC)以及 設定請求頭內容 (字典型別allHTTPHeaderFields;)等等

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

1.設定請求超時等待時間(超過這個時間就算超時,請求失敗)
- (void)setTimeoutInterval :(NSTimeInterval)seconds;
2.設定請求方法(比如GET和POST)
- (void)setHTTPMethod:(NSString*)method;
3.設定請求體
- (void)setHTTPBody:(NSData *)data;
4.設定請求頭
- (void)setValue:(NSString *)value forHTTPHeaderField:(NSString *)field;

 NSString *urlStr = @"http://120.25.226.186:32812/login";
    NSURL *url = [NSURL URLWithString:urlStr];
    // 關於post 方式的話 ,必須使用可變的請求,只有可變請求才能進行 協議方式的設定, 以及請求體等等的設定。
    // 因為不可變請求的話  是預設 get方式的。
    // post的方式比較  儲存了 使用者的隱私安全 ,將其中使用者比較隱私的東西,儲存在請求體中吧。
    
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    
    // 設定請求方式  為POST   記住 必須大寫。
    request.HTTPMethod = @"POST";
    
    // 設定請求體 ,返回data,  直接用nsstring的方法  ,進行轉換。
    request.HTTPBody = [@"username=520it&pwd=520it" dataUsingEncoding:NSUTF8StringEncoding];
    
    // 最大訪問超時時間。
    request.timeoutInterval = 10;
    
    // 設定請求頭內容  ,但一般不要求設定 。使用者的手機系統
    [request setValue:@"ios 9.0" forHTTPHeaderField:@"use-Agent-to"];
    
    [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
        NSString *dataStr = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
        NSLog(@"%@",dataStr);
    }];

相關文章