2015-12-07 69 views
1

我的最終目標是在處理內存中的響應時在後臺發出http請求。根據我的理解,後臺請求必須使用自定義代理(這意味着我不能使用dataTaskWithRequest(request, completionHandler)),並且爲了處理內存中的響應,我必須使用數據任務(這意味着我無法使用下載任務連同URLSession(session, downloadTask, didFinishDownloadingToURL))。iOS NSURLSession使用自定義代理處理數據任務的完成

根據這個:https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/URLLoadingSystem/NSURLSessionConcepts/NSURLSessionConcepts.html#//apple_ref/doc/uid/10000165i-CH2-SW1它看起來好像沒有任何委託方法在完成時被調用用於數據任務。是否通過代理通過URLSession(session, dataTask, data)與單個NSData片段一起處理響應? https://developer.apple.com/library/ios/documentation/Foundation/Reference/NSURLSessionDataDelegate_protocol/index.html#//apple_ref/occ/intfm/NSURLSessionDataDelegate/URLSession:dataTask:didReceiveData:不存在將整個最終響應作爲單個NSData實例處理的委託方法?

回答

3

對於需要立即顯示的少量數據(如API調用或像化身等小圖像),dataTaskWithRequest(request, completionHandler)是您想要的方法。它設置了一個異步任務,這意味着當你啓動任務時,執行將立即返回到你的代碼,當你的應用程序運行時,任務將負責下載數據並將其緩存在內存中。一旦所有下載任務完成,它將調用您的completionHandler,讓它知道它已完成並且數據已準備就緒。它會將數據傳遞給您的處理程序作爲參數。

對於較大的文件,如播客,視頻和大圖像,即使用戶開始查看另一個應用程序並且您的應用程序被暫停,您也會希望iOS爲您下載該文件。然後,您將要使用NSURLSessionDownloadTask以及後臺會話配置backgroundSessionConfigurationWithIdentifier:和自定義代理。您的自定義代理將需要實施方法URLSession:downloadTask:didFinishDownloadingToURL:。當這個方法被調用時,你可以閱讀在url的文件,將使用類似這樣的代碼被傳遞給你的內容:

let data = NSData(contentsOfURL: url) 

原因後臺下載iOS應用程序的退出等處理後仍然存在這就是說,iOS希望能夠代表像播客,視頻等不同應用程序繼續下載多個文件。如果用戶使用高速網絡,則在內存中下載多個大文件可以快速佔用所有設備的內存,所以它們會在下載時被存儲。同樣,在使用NSData(contentsOfURL:)將整個文件讀入內存之前,應該記住文件大小。

下面是一個如何將所有東西放在一起的工作示例。在iOS的操場上粘貼並查看圖像,你會得到:

import UIKit 

class MyDelegate: NSObject, NSURLSessionDelegate, NSURLSessionDownloadDelegate { 
    func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didFinishDownloadingToURL location: NSURL) { 
    if let data = NSData(contentsOfURL: location) { 
     // work with data ... 
     UIImage(data: data) 
    } 
    } 
} 

let configuration = NSURLSessionConfiguration.backgroundSessionConfigurationWithIdentifier("my-session-identifier") 
let delegate = MyDelegate() 
let session = NSURLSession(configuration: configuration, delegate: delegate, delegateQueue: nil) 
let url = NSURL(string: "https://pbs.twimg.com/profile_images/473550724433858560/tuHsaI2U.png")! 
let task = session.downloadTaskWithURL(url) 
task.resume() 

// this allows the code to run in a playground 
import XCPlayground 
XCPlaygroundPage.currentPage.needsIndefiniteExecution = true 
+0

我是從蘋果公司的文檔的印象是,你不能用'dataTaskWithRequest(請求,completionHandler)'如果你要處理在後臺響應,你必須使用'NSURLSessionDelegate',它通過一些複雜的過程在你的應用程序生命週期中被實例化(甚至還沒有到達那裏......)https://developer.apple.com/library/ios/文檔/ Cocoa/Conceptual/URLLoadingSystem /文章/使用NSURLSession.html#// apple_ref/doc/uid/TP40013509-SW44 – user1084447

+0

@ user1084447我誤解了你最初在背景中的含義。我已經擴大瞭解決iOS應用背景的答案。希望這回答它! – hashemi

+0

@hashemi不需要使用NSData。你可以使用UIImage(contentsOfFile:location.path!) –