iOS 原生后台下载 断点续传 关键点.

后台下载

就需要按照苹果的规定,使用URLSessionDownloadTask

关于后台下载,其实苹果有提供文档---Downloading Files in the Background

URLSession

首先,如果需要实现后台下载,就必须创建Background Sessions

private lazy var urlSession: URLSession = { 
   let config = URLSessionConfiguration.background(withIdentifier: "MySession")
   config.isDiscretionary = true    
   config.sessionSendsLaunchEvents = true    
   return URLSession(configuration: config, delegate: self, delegateQueue: nil)
   }()

通过这种方式创建的URLSession,其实是__NSURLBackgroundSession:

  • 必须使用background(withIdentifier:)方法创建URLSessionConfiguration,其中这个identifier必须是固定的,而且为了避免跟其他 App 冲突,建议这个identifier跟 App 的Bundle ID相关
  • 创建URLSession的时候,必须传入delegate
  • 必须在 App 启动的时候创建Background Sessions,即它的生命周期跟 App 几乎一致,为方便使用,最好是作为AppDelegate的属性,或者是全局变量,原因在后面会有详细说明。

URLSessionDownloadTask

只有URLSessionDownloadTask才支持后台下载

let downloadTask = urlSession.downloadTask(with: url)
downloadTask.resume()

 

断点续传

苹果的官方文档----Pausing and Resuming Downloads

URLSessionDownloadTask 的断点续传依靠的是resumeData

// 取消时保存resumeData
downloadTask.cancel { resumeDataOrNil in
    guard let resumeData = resumeDataOrNil else {
      // download can't be resumed; remove from UI if necessary
      return 
      }
    self.resumeData = resumeData
}

// 或者是在session delegate 的 urlSession(_:task:didCompleteWithError:) 方法里面获取
func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
    guard let error = error else {
        // Handle success case.
        return
    }
    let userInfo = (error as NSError).userInfo
    if let resumeData = userInfo[NSURLSessionDownloadTaskResumeData] as? Data {
        self.resumeData = resumeData
    }
    // Perform any other error handling.
}

// 用resumeData恢复下载
guard let resumeData = resumeData else {
    // inform the user the download can't be resumed
    return
}
let downloadTask = urlSession.downloadTask(withResumeData: resumeData)
downloadTask.resume()
self.downloadTask = downloadTask

 

并非所有下载都可以恢复。有关恢复下载必须满足条件,另外,使用后台配置的下载将自动处理恢复,因此仅非后台下载才需要手动恢复。cancel(byProducingResumeData:)

 

最后 官方推荐。isDiscretionary 设置为ture   

一个布尔值,该值确定是否可以由系统决定是否调度后台任务以实现最佳性能。

实际使用过程中发现。最好为false 因为 新机型很有可能无缘无故下载不响应(找了好长时间什么原因。。。。)

 

部分老机型 App进行前后台切换,会导致urlSession(_:downloadTask:didWriteData:totalBytesWritten:totalBytesExpectedToWrite:)方法不调用 自己找机会弥补

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值