应用程序杀死,如何保证断点续传?

1. 使用 AFHTTPRequestOperation 实现断点续传的代码

    // 1 指定下载文件地址 URLString

 // 2 获取保存的文件路径 filePath

 // 3 创建 NSURLRequest

 NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:URLString]];

 unsigned long long downloadedBytes = 0;

 if([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {

 // 3.1 若之前下载过 , 则在 HTTP 请求头部加入 Range

    // 获取已下载文件的 size

    downloadedBytes = [self fileSizeForPath:filePath];

    // 验证是否下载过文件

    if(downloadedBytes > 0) {

        // 若下载过 , 断点续传的时候修改 HTTP 头部部分的 Range

        NSMutableURLRequest *mutableURLRequest = [request mutableCopy];

        NSString *requestRange =

        [NSString stringWithFormat:@"bytes=%llu-", downloadedBytes];

        [mutableURLRequest setValue:requestRange forHTTPHeaderField:@"Range"];

        request = mutableURLRequest;

    }

 }

 // 4 创建 AFHTTPRequestOperation

 AFHTTPRequestOperation *operation

  = [[AFHTTPRequestOperation alloc] initWithRequest:request];

 // 5 设置操作输出流 , 保存在第 2 步的文件中

 operation.outputStream = [NSOutputStream

 outputStreamToFileAtPath:filePath append:YES];

 // 6 设置下载进度处理 block

 [operation setDownloadProgressBlock:^(NSUInteger bytesRead,

 long long totalBytesRead, long long totalBytesExpectedToRead) {

 // bytesRead 当前读取的字节数

 // totalBytesRead 读取的总字节数 , 包含断点续传之前的

 // totalBytesExpectedToRead 文件总大小

 }];

 // 7 设置 success 和 failure 处理 block

 [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation

 *operation, id responseObject) {

 } failure:^(AFHTTPRequestOperation *operation, NSError *error) {

 }];

 // 8 启动 operation

 [operation start];

2. NSURLConnection 的实现

 // 请求失败处理

 func connection(connection: NSURLConnection,

 didFailWithError error: NSError) {

    self.failureHandler(error: error)

 }

 // 接收到服务器响应是调用

 func connection(connection: NSURLConnection,

  didReceiveResponse response: NSURLResponse) {

    ifself.totalLength != 0 {

        return

    }

    self.writeHandle = NSFileHandle(forWritingAtPath:

    FileManager.instance.cacheFilePath(self.fileName!))

    self.totalLength = response.expectedContentLength + self.currentLength

 }

 // 当服务器返回实体数据是调用

 func connection(connection: NSURLConnection, didReceiveData data: NSData) {

    let length = data.length

    // move to the end of file

    self.writeHandle.seekToEndOfFile()

    // write data to sanbox

    self.writeHandle.writeData(data)

    // calculate data length

    self.currentLength = self.currentLength + length

    print("currentLength\(self.currentLength)-totalLength\(self.totalLength)")

    if(self.downloadProgressHandler != nil) {

        self.downloadProgressHandler(bytes: length, totalBytes:

        self.currentLength, totalBytesExpected: self.totalLength)

    }

 }

 // 下载完毕后调用

 func connectionDidFinishLoading(connection: NSURLConnection) {

    self.currentLength = 0

    self.totalLength = 0

    //close write handle

    self.writeHandle.closeFile()

    self.writeHandle = nil

    let cacheFilePath = FileManager.instance.cacheFilePath(self.fileName!)

    let documenFilePath = FileManager.instance.documentFilePath(self.fileName!)

    do{

        tryFileManager.instance.moveItemAtPath(cacheFilePath, toPath: documenFilePath)

    } catchlet e as NSError {

        print("Error occurred when to move file: \(e)")

    }

    self.successHandler(responseObject:fileName!)

 }

3.NSURLSessionDataTask 的实现

 // 接收数据

 func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask,

 idReceiveData data: NSData) {

    //. . .

 }

 // 接收服务器响应

 func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask,

 didReceiveResponse response: NSURLResponse, completionHandler:

  (NSURLSessionResponseDisposition) -> Void) {

    // . . .

    completionHandler(.Allow)

 }

 // 请求完成

 func URLSession(session: NSURLSession, task: NSURLSessionTask,

  didCompleteWithError error: NSError?) {

    iferror == nil {

        // . . .

        self.successHandler(responseObject:self.fileName!)

    } else{

        self.failureHandler(error:error!)

    }

 }

4. NSURLSessionDownloadTask 的实现

 //UI 触发 pause

 func pause(){

    self.downloadTask?.cancelByProducingResumeData({data -> Void in

        ifdata != nil {

 data!.writeToFile(FileManager.instance.cacheFilePath(self.fileName!),

 atomically: false)

 }

        })

    self.downloadTask = nil

 }

 // MARK: - NSURLSessionDownloadDelegate

 func URLSession(session: NSURLSession, downloadTask:

 NSURLSessionDownloadTask, didWriteData bytesWritten: Int64,

 totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) {

    if(self.downloadProgressHandler != nil) {

        self.downloadProgressHandler(bytes: Int(bytesWritten),

         totalBytes: totalBytesWritten, totalBytesExpected: totalBytesExpectedToWrite)

    }

 }

 func URLSession(session: NSURLSession, task: NSURLSessionTask,

 didCompleteWithError error: NSError?) {

    iferror != nil {//real error

        self.failureHandler(error:error!)

    }

 }

 func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask,

  didFinishDownloadingToURL location: NSURL) {

    let cacheFilePath = FileManager.instance.cacheFilePath(self.fileName!)

    let documenFilePath = FileManager.instance.documentFilePath(self.fileName!)

    do{

        ifFileManager.instance.fileExistsAtPath(cacheFilePath){

            tryFileManager.instance.removeItemAtPath(cacheFilePath)

        }

        tryFileManager.instance.moveItemAtPath(location.path!, toPath: documenFilePath)

    } catchlet e as NSError {

        print("Error occurred when to move file: \(e)")

    }

    self.successHandler(responseObject:documenFilePath)

 }

可以参考一个作者写的GitHub搜索KillAppDownload,进行了充分的缓存

参考文章写得很不错 http://www.cocoachina.com/ios/20160728/17219.html

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 在苹果彻底弃用NSURLConnection之后自己总结的一个网上的内容,加上自己写的小Demo,很多都是借鉴网络...
    付寒宇阅读 4,538评论 2 13
  • iOS开发系列--网络开发 概览 大部分应用程序都或多或少会牵扯到网络开发,例如说新浪微博、微信等,这些应用本身可...
    lichengjin阅读 4,066评论 2 7
  • 使用NSURLConnection实现下载 1. 小文件下载 第一种方式(NSData) 第二种方式(NSURLC...
    搁浅的青蛙阅读 2,011评论 3 10
  • 同步请求和异步请求- 同步请求:阻塞式请求,会导致用户体验的中断- 异步请求:非阻塞式请求,不中断用户体验,百度地...
    WangDavid阅读 680评论 0 0
  • 我们先看一下AFNetworking.h文件都给了我们什么方法 #import <Foundation/Found...
    潇岩阅读 775评论 0 1

友情链接更多精彩内容