iOS中利用NSURLSession进行文件断点下载
iOS中利用NSURLSession进行文件断点下载
不孤独的美食家 发表于2年前
iOS中利用NSURLSession进行文件断点下载
  • 发表于 2年前
  • 阅读 10272
  • 收藏 27
  • 点赞 9
  • 评论 50

腾讯云 技术升级10大核心产品年终让利>>>   

摘要: 我们有时在边聊天边下载大文件时,感觉很卡,这时可以暂停下载任务,聊完天再继续下载文件。这就是断点下载。iOS中利用NSURLSession可以进行文件断点下载,下面就一起来实现它把!! 说明:感谢网友TomLoveSweet的建议!在resume方法中,应该是[self.task resume];不是[self resume].还有这个方法中第一句需要用self.task接收一下。对这个错误,我表示深感歉意!

                                      第一部分 知识储备

 1.对NSURLSesiion的认识

      NSURLSesiion是苹果在iOS7推出的一个类,它具备了NSURLConnection所具备的方法,同时也比它更强大。苹果推出它的目的大有取代NSURLConnection的趋势或者目的。

 2.  NSURLSesiion的作用

     实现对文件的下载与上传。在NSURLSesiion中,任何请求都可以被看做是一个任务。而NSURLSesiionData 有两个子类:NSURLSessionDownlaodTask实现文件下载和NSURLSessionUploadTask实现文件上传。

 3.NSURLSession的获取

    NSURLSession的获取可以用NSURLSessionDownloadTaskdelegate的方法获取,但是必须得遵循这个协议。获取如下:

        NSURLSessionDonfiguration* configuration=[NSURLSessionDonfiguration defaultSessionconfiguration];

        self.session=[NsURLSession sessionWithConfiguration:NSURLSessionDonfiguration delegate: self  delegateQueue:[NSOperationQueue mainQueue]];

 4.下载任务的创建

    NSURLSessionDownlaodTask* task=[self.session downloadTaskWithURL:url]

 5.NSURLSessionDownloadDelegate的代理方法:

    它有三个方法:

 6. 沙盒路径的获取

    NSString *path=[NSSearchPathForDiretoriesInDomains(NSDocumentDirectoriy, NSUserDomainMask, YES )  lastObject];

 7.caches路径的获取及里面文件名的创建

   NSString *caches=[NSSearchPathForDiretoriesInDomains(NSCachesDirectoriy, NSUserDomainMask, YES )  lastObject];  

NSString* filename=[caches stringByAppendingPathComponent:downloadTask.response.suggestedname];

                                第二部分  对程序几个属性的说明

 1. resumeData

           该参数包含了继续下载文件的位置信息。也就是说,当你下载了10M得文件数据,暂停了。那么你下次继续下载的时候是从第10M这个位置开始的,而不是从文件最开始的位置开始下载。因而为了保存这些信息,所以才定义了这个NSData类型的这个属性:resumeData

2.  task

           该参数的类型是NSURLSessionDownloadTask。因为在程序调用暂停(pause)这个方法时,必须拥有这个属性,怎么拿到它了?最好的办法就是让控制器拥有这个属性。

3. session

           该参数的类型是NSURLSession.在程序调用继续下载(resume)这个方法时,必须拥有这个session。因为之前的任务task被取消了,无法在复用了,所以用懒加载的方法,让session只创建一次,同时也让控制器拥有了这个属性。

                             第三部分 程序实现流程(伪代码)

下面是文件下载的思路:


                       

   

                                      第四部分 UI界面搭建

          

                   由于程序UI界面搭建十分容易,故在此不详细叙述。


                                      第五部分  程序特别注意点

1.  在调用pause这个方法时,存在着一定的风险,因为self对task进行了强引用,task又对block进行了引用,block又对self进行引用,这就形成了循环使用。怎么解决这个问题呢?

解决方法:对self进行弱引用 __weak typedef(self)   vc=self

2. 如果设置了completion和block,又实现了代理方法,程序优先执行block

                                      第六部分 代码截图



                                      第七部分   程序截图



     


共有 人打赏支持
粉丝 89
博文 159
码字总数 48705
作品 1
评论 (50)
TomLoveSweet
resum 方法里面的那个[self resume]应该是[self.task resume]吧?
不孤独的美食家

引用来自“TomLoveSweet”的评论

resum 方法里面的那个[self resume]应该是[self.task resume]吧?
检查了一下,是的,感谢你的及时建议!!谢谢!
杨雯德
你好,请问关闭程序是怎么实现断点续传的那,我在程序关闭前走了所有的下载的暂停,但是[weakSelf.downloadTask cancelByProducingResumeData:^(NSData *resumeData) {

NSLog(@"%@",resumeData);
weakSelf.receiveData = resumeData;

}];block不走,请问你是怎么实现的那
不孤独的美食家
应该是要配置NSURLSessionConfiguration为后台下载,NSURLSessionConfiguration* c=[NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:@"background"];
杨雯德

引用来自“妖精的尾巴ing”的评论

应该是要配置NSURLSessionConfiguration为后台下载,NSURLSessionConfiguration* c=[NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:@"background"];
能具体点嘛, 我这块还是不行
不孤独的美食家

引用来自“妖精的尾巴ing”的评论

应该是要配置NSURLSessionConfiguration为后台下载,NSURLSessionConfiguration* c=[NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:@"background"];

引用来自“杨雯德”的评论

能具体点嘛, 我这块还是不行
- (void)viewDidLoad { [super viewDidLoad]; // 文件的临时保存路径为:Library/Caches/ 里面,程序进入后台后 观察这个文件的大小变化 NSLog(@"%@", NSHomeDirectory()); NSURL *url = [NSURL URLWithString:@"http://free2.macx.cn:8182/tools/network/Thunder266.dmg"]; NSURLSessionConfiguration *config = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:@"kBackTaskID"]; NSURLSession *session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:[NSOperationQueue mainQueue]]; NSURLSessionDownloadTask *downTask = [session downloadTaskWithURL:url]; [downTask resume]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } -(void)moveDownloadFile:(NSURL *)location withNewFile:(NSString *)newFile { NSString *filePath = [NSHomeDirectory() stringByAppendingPathComponent:newFile]; NSURL *toUrl = [NSURL fileURLWithPath:filePath]; NSFileManager *fileManager = [NSFileManager defaultManager]; BOOL exist = [fileManager fileExistsAtPath:filePath]; if (!exist) { [fileManager moveItemAtURL:location toURL:toUrl error:NULL]; } NSLog(@"文件保存成功"); } - (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location { [self moveDownloadFile:location withNewFile:@"Documents/file.dmg"]; } 你参考下这一块代码吧,希望有帮助!
风画007
NSURLSession下载的时候可以显示已下载了多少吗。用label显示出来
风画007
谢谢了
不孤独的美食家

引用来自“风画007”的评论

NSURLSession下载的时候可以显示已下载了多少吗。用label显示出来
当前下载进度:后面就是用label显示出来的
不孤独的美食家
谢谢你的评论!
风画007

引用来自“妖精的尾巴ing”的评论

谢谢你的评论!
不是的啊,我说的的,用三个label,一个显示下载的速度,一个显示已下载的M ,一个显示文件总大小,这个可以实现吗
风画007

引用来自“妖精的尾巴ing”的评论

谢谢你的评论!
前面意思没有表达清楚不好意思啊
不孤独的美食家

引用来自“妖精的尾巴ing”的评论

谢谢你的评论!

引用来自“风画007”的评论

不是的啊,我说的的,用三个label,一个显示下载的速度,一个显示已下载的M ,一个显示文件总大小,这个可以实现吗
可以,在代理方法中,设置方法和设置当前下载大小一样,参照着做就行了思路是一样的,如果还是不懂,可以参考苹果官方文档,
不孤独的美食家

引用来自“妖精的尾巴ing”的评论

谢谢你的评论!

引用来自“风画007”的评论

前面意思没有表达清楚不好意思啊
没关系的
风画007

引用来自“妖精的尾巴ing”的评论

谢谢你的评论!

引用来自“风画007”的评论

前面意思没有表达清楚不好意思啊

引用来自“妖精的尾巴ing”的评论

没关系的
谢谢啊
不孤独的美食家

引用来自“妖精的尾巴ing”的评论

谢谢你的评论!

引用来自“风画007”的评论

前面意思没有表达清楚不好意思啊

引用来自“妖精的尾巴ing”的评论

没关系的

引用来自“风画007”的评论

谢谢啊
对于你有帮助,这篇博客也就没有白写了!
Je_amo
你好,请问下如何设置下载过程中临时文件的存放位置,也就是下载完成回调方法里面的location的路径。
renjing_123455
你好像没有考虑到vc 、NSURLSession以及NSURLSession的delegate属性(是一个强引用类型)形成循环引用的问题
renjing_123455
还有就是下载的逻辑还不太完善,你应该在resume方法中,将新建的任务赋值给全局变量task的,不然,当你再次点击暂停的时候,因为task变量是空的,所以会没有效果的,也就是说,当前任务暂停不了;不仅如此,由于resumedata也是空的,那就会运行start,又重新一次下载。总之,现在你的逻辑就是:start --》pause --》resume --》pause(相当于 start)
不孤独的美食家

引用来自“Je_amo”的评论

你好,请问下如何设置下载过程中临时文件的存放位置,也就是下载完成回调方法里面的location的路径。
在下载完成的方法里调用,设置
×
不孤独的美食家
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: