嚴格意義上來說,iOS並不能像Android一樣,真的在后台開啟一個下載Service,一直下載。但是它可以進行在系統允許范圍內的后台上傳和下載。
當使用
NSURLSessionConfiguration* sessionConfig = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:identifier];
NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfig delegate:self delegateQueue:self.operationQueue];
創建一個Session后,由此Session創建出的NSURLSessionDownloadTask 和 NSURLSessionUploadTask 都會被交給系統的Background Transfer Services負責上傳下載。 這種方法創建的task,不支持block形式的創建方法,必須使用比較原始的delegate回調方式。而且目前NSURLSessionDataTask對background模式的支持不好,切入后台后, 沒有任何系統回調函數, 過一段時間再把程序切入前台直接報錯。至於原因,有如下帖子說明:
https://stackoverflow.com/questions/39639268/ios-background-task-using-nsurlsessiondatatask
其中的主要意思是,NSURLSessionDataTask是把數據保存在內存中的,而Background Transfer Services無法跨進程讀取內存數據。但是實際上,官方文檔並沒有說明DataTask不支持后台模式,很可能是目前的iOS版本里存在bug。
官方推薦的使用方法是在一個Session中,直接將需要處理的任務全部開啟,程序進入后台,這些任務全部下載完成后,系統會通知程序。這種模式很適合下載的Url數量很少的情況,比如只需要下載幾個url中的數據。但是如果需要下載幾十個或是上百個url的資源,我們就不能一下子發起那么多的請求,服務器很可能無法及時響應,導致請求超時出錯。那么想要達到后台下載的效果,就需要把眾多請求分組放入多個Session,一個Session中的所有下載完成后,系統回產生回調,我們在系統回調中再次開啟新的Session,繼續下載。