iOS 網路請求 筆記

來源:互聯網
上載者:User

標籤:

有關網路請求的類(該圖片來自:developer.apple.com)

一、url請求

網路請求的組成部分有伺服器位址、請求參數,以及請求方式。在iOS中,一個網路請求用NSURLRequest(或者其子類NSURLMutableRequest)來表示。

NSURLRequest適合於get請求,NSURLMutableRequest可以是post請求。

get方式下,伺服器位址和請求參數都可以明文包含在url中,可以直接使用這個url來建立NSURLRequest(或者NSURLMutableRequest)。

post方式下,伺服器位址用NSURL來表示,請求參數可以封裝到NSData中(也可以以檔案或者流的形式儲存)。由於需要將伺服器位址和請求參數分開,所以需要用到NSURLMutableRequest類。用伺服器位址的url建立NSURLMutableRequest對象,然後將封裝了請求參數的NSData對象添加到這個NSURLMutableRequest對象中。樣本如下:

NSURL *url=[NSURL URLWithString:@“http://ipad-bjwb.bjd.com.cn/DigitalPublication/publish/Handler/APINewsList.ashx"];NSData *data=[@"date=20151101&startRecord=1&len=5&udid=1234567890&terminalType=Iphone&cid=213" dataUsingEncoding:NSUTF8StringEncoding];

然後將伺服器位址與請求參數加入到NSURLMutableRequest對象中:

NSMutableURLRequest *request=[NSMutableURLRequest requestWithURL:url cachePolicy:0 timeoutInterval:60];request.HTTPMethod[email protected]"post";//指明請求方式為post,預設為getrequest.HTTPBody=data;

這樣就準備好了一個網路請求,接下來就是如何去執行這個網路請求的問題。

二、執行url請求

執行url請求可以使用iOS原生API也可以使用第三方庫。

執行url請求的兩個原生方法:
(1)NSURLSession
(2)NSURLConnection
iOS 7.0 以後推薦使用NSURLSession,以前使用NSURLConnection。
NSURLSession、NSURLConnection都可以發送和接收以NSData或者檔案的形式儲存的資料.

實現url請求的第三方庫有afNetworking、sdWebImage等。

1.兩個原生方法的基本使用思路

(1)每個項目都有一個NSURLSession對象,可以通過[NSURLSession sharedSession]方法來擷取它,然後就可以用它來建立請求任務。該任務調用resume方法後開始執行。請求任務有三種,上傳、下載、資料。通過NSURLSession來執行url請求是非同步。

(2)NSURLConnection直接執行send方法(類方法)發送請求,可以選擇同步也可以選擇非同步。非同步發送請求接收資料的話可以使用block接收,也可以使用代理。注意如果使用代理來接收資料,資料會是斷續接收的。通常使用block比較方便。

同步和非同步區別就是,同步就是執行完網路要求方法後,要等到網路請求得到響應並完成資料轉送之後才返回,非同步就是發送完請求之後馬上返回。

2. NSURLSession詳解

擷取session可以通過初始化方法,也可以直接使用項目預設的session對象,通過sharedSession方法擷取。初始化session對象需要指定代理,如果指定為nil,就是使用系統預設的代理。

(1)session的分類

session分為3種:

  • 預設的(default session):會將儲存資料存到硬碟上。
  • 短暫的(ephemeral session):不會儲存任何資料到硬碟上,只會佔用記憶體,當session釋放了,所有的資料也就沒有了。
  • 背景(background session):和預設的session的區別在於會用獨立的過程來處理資料轉送。

初始化session的時候需要指定一個NSURLSessionConfiguration對象,session的類型就由這個對象的類型來確定。

(2)任務task的分類

任務分為3種,資料、下載、上傳:

  • data task資料任務:發送和接收NSData形式的資料
  • download task下載任務:解析檔案形式的資料,支援app沒有啟動並執行時候在後台執行。
  • upload task上傳任務:傳送檔案形式的資料,也支援後台執行。
(3)任務task和session的關係
  • 任務的初始化和任務的管理都由session來完成。

  • 每個session對象管理著它自己建立的任務。

  • 任務建立後需要執行resume方法,session才會處理它。

  • 任務處理的具體操作是由session的代理來完成的,也就是說具體的處理會寫在代理方法中。

(4)利用session完成後台傳輸

需要注意的問題:

  • 只有後台類型的session才可以建立支援後台傳輸的任務(下載任務或上傳任務)。而且後台上傳只支援檔案上傳,如果上傳的是NSData對象或者資料流,在app退出後就會斷掉。
  • 背景工作只支援http和https協議,不支援自訂協議。
  • 如果後台傳輸的任務是在app已經進入了後台之後才初始化的,那麼session的NSURLSessionConfiguration對象的discretionary屬性值為true。
  • 由於網路錯誤導致的後台上傳或後台下載任務失敗,系統會自動重新嘗試執行這些任務,所以不需要自己寫代碼來重新執行失敗的背景工作。

背景工作與app的互動:

背景工作的特點就是運行在後台,當app不在啟動並執行時候背景工作仍然可以運行。

上面說過,任務的處理是由session的代理方法來完成的,但是當app沒有啟動並執行時候,session已經被釋放,這時候背景工作怎麼和建立這個任務的session重新關聯起來呢?

這個問題iOS系統已經有一套完整的機制去處理它。是這樣的:當背景工作完成或者需要認證的時候,如果app沒有在運行,系統就會喚醒app,並調用app delegate的(void)application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier completionHandler:(void (^)())completionHandler方法。這個方法就是特地寫來處理背景工作的,下面所描述的內容都圍繞這個方法來展開。

需要重寫在這個方法,在這個方法中讓背景工作和session重新關聯起來。由於建立它的session已經釋放,要找回它不可能,實際的做法是建立一個和它一樣的session,然後讓任務與這個session關聯起來。具體就是用這個方法的參數identifier來建立一個NSURLSessionConfiguration對象,並且用這個NSURLSessionConfiguration對象建立一個session,這個session就可以當成是原來的session了。神奇的是,只要這樣建立了session,正在啟動並執行任務就會自動和它關聯起來,至於是怎麼做到了,不需要操心,系統已經解決了。

留意到這個方法有一個block類型的參數completionHandler,它的意義在於,一旦它被執行就表明背景工作處理完成,因此系統自喚醒app之後就會一直等待completionHandler的執行,以便讓app重新停止運行。因此,要記得把completionHandler傳給session的代理,並且在session的代理方法URLSessionDidFinishEventsForBackgroundURLSession:中調用它,這樣就實現了在最後一個任務處理完畢以後讓app再次進入後台。

在正在啟動並執行任務已經和session重新取得聯絡之後就會調用其代理的相關方法,如果是背景工作完成,就會調用URLSession:downloadTask:didFinishDownloadingToURL:方法。如果是需要認證,就會調用URLSession:task:didReceiveChallenge:completionHandler:方法或者URLSession:didReceiveChallenge:completionHandler:方法。

官網例子:https://developer.apple.com/library/ios/samplecode/SimpleBackgroundTransfer/Introduction/Intro.html#//apple_ref/doc/uid/DTS40013416

(4)下載檔案

與檔案下載有關的協議方法:

  • URLSession:downloadTask:didFinishDownloadingToURL:
    檔案下載完成後調用,可以擷取下載好的檔案的url
  • URLSession:downloadTask:didWriteData:totalBytesWritten:totalBytesExpectedToWrite:
    下載過程中調用
  • URLSession:downloadTask:didResumeAtOffset:expectedTotalBytes:
    該方法在開始恢複一個失敗的下載任務之後調用
  • URLSession:task:didCompleteWithError:
    下載任務完成或終止後調用,如果任務出錯,可以擷取到NSError對象
  • 終止下載任務
    可以調用NSURLSessionDownloadTask對象的方法:cancelByProducingResumeData:
  • 恢複下載任務
    可以調用sessiondownloadTaskWithResumeData:downloadTaskWithResumeData:completionHandler:
    這裡的resumeData從協議方法URLSession:task:didCompleteWithError:中的NSError對象的userInfo字典中會有,對應key為NSURLSessionDownloadTaskResumeData
(5)重新導向

相關協議方法:

- (void)URLSession:(NSURLSession *)session?              task:(NSURLSessionTask *)task?willPerformHTTPRedirection:(NSHTTPURLResponse *)response?        newRequest:(NSURLRequest *)request? completionHandler:(void (^)(NSURLRequest *))completionHandler

對於預設的session和暫時的session管理的url請求任務發生重新導向時就會調用這個方法,而背景工作發生重新導向會直接服從重新導向。

在這個方法裡面,可以擷取到新的url請求,調用completionHandler(request);就會允許重新導向。如果調用completionHandler(nil);就相當於拒絕重新導向。當然也可以調用completionHandler(otherRequest);實現自訂重新導向。

iOS 網路請求 筆記

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.