iOS NSURLSession后台下载和断点续传
来源:互联网 发布:oracle sql书写技巧 编辑:程序博客网 时间:2024/05/22 18:00
前几天面试被人问到后台下载的问题,当时就GG了,之前写Andriod的时候,用service写过,但是iOS没有做过这方面的。回去后查了一些资料,就有了这篇博文。
NSURLSession出来之后,我们可以很容易实现后台下载这种任务,简单使用backgroundSessionConfigurationWithIdentifier:就OK了。
下面讲解如何实现:
首先让我们在ViewController的类拓展里添加如下代码:
@interface ViewController ()<NSURLSessionDelegate,NSURLSessionDownloadDelegate,NSURLSessionTaskDelegate>@property (nonatomic,strong) NSURLSession *session;@property (nonatomic,strong) NSURLSessionDownloadTask *task;@end
我们在里面声明里NSURLSession和NSURLSessionDownTask的属性,还实现了NSURLSessionDelegate,NSURLSessionDownloadDelegate,NSURLSessionTaskDelegate这三个必须实现的代理。
接着我们去实现下载的方法:
- (void)downloadBackground{ NSURLSessionConfiguration *config = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:@"download"]; //系统根据当前性能自动处理后台任务的优先级 config.discretionary = YES; _session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:nil]; //下面两个是不同的文件,一个是一张图片,一个是微博,大家可以选择不同的网址去实验 // http://farm3.staticflickr.com/2846/9823925914_78cd653ac9_b_d.jpg // http://dlsw.baidu.com/sw-search-sp/soft/3f/12289/Weibo.4.5.3.37575common_wbupdate.1423811415.exe NSURL *url = [NSURL URLWithString:@"http://dlsw.baidu.com/sw-search-sp/soft/3f/12289/Weibo.4.5.3.37575common_wbupdate.1423811415.exe"]; NSURLRequest *request = [NSURLRequest requestWithURL:url]; _task = [_session downloadTaskWithRequest:request]; [_task resume];}
NSURLSession的固定写法,定义后台下载的NSURLSessionConfiguration,定义session,再定义一个request和task,启动task。
这样就可以了吗?当然不是,我们还需要实现相应的代理方法,再添加下面的方法
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite{ //下载过程不断回调 NSLog(@"当前进度%f%%",totalBytesWritten * 1.0 / totalBytesExpectedToWrite * 100);}- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location{ //下载结束回调,注意这里得到的文件是一个临时文件,为了保存这个文件,我们需要把它copy到Document目录下 NSLog(@"file--%@,path--%@",downloadTask.description,location);}
好了,在viewDidLoad函数中调用downloadBackground,现在运行工程,应该可以看到不断打印的进度,在模拟器按一下command+shift+h回到桌面,发现程序依然在下载,并没有停滞,不过最后发现打印出来的path是.tmp文件,像上面注释说的,这里我们得到的是一个临时文件,我们必须将这个文件copy到Document目录下。当然如果你什么都看不到,只看到一条报错信息,请确保你已经在你的plist文件加入以下键值对:
<key>NSAppTransportSecurity</key> <dict> <key>NSAllowsArbitraryLoads</key> <true/> </dict>
为什么要这样写?请度娘!!!!
好了,现在让我们实现copy文件的函数
- (void)copyFileAtPath:(NSString *)path{ NSFileManager *fileManager = [NSFileManager defaultManager]; NSError *error; NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentDirectory = [paths objectAtIndex:0]; NSLog(@"document--%@",documentDirectory); //测试图片的网址,改这个 // NSString *toPath = [documentDirectory stringByAppendingPathComponent:@"1.jpg"]; NSString *toPath = [documentDirectory stringByAppendingPathComponent:@"weibo.exe"]; if (![fileManager fileExistsAtPath:toPath]) { [fileManager copyItemAtPath:path toPath:toPath error:&error]; if (error) { NSLog(@"copy error--%@",error.description); } }}
上面这个函数首先得到Document文件夹的路径,再拼接出文件路径,最后就是判断文件是否存在,不存在就复制。
请在下载完成的回调函数里调用这个方法,等到下载完成之后,复制控制台打印的document路径,在桌面按command+shift+g,会弹出前往的窗口,粘贴刚刚复制的路径,点击前往,你会看到这样的图片:
做到这里,后台下载就完成了。不过我们可以做得更好一些,让我们给它加上断点续传的功能。先让我们用StoryBoard拉个简单的界面,不熟悉StroyBoard的请自行度娘。界面大概是这样的:
接着在类拓展里添加下面的属性:
@property (nonatomic,strong) NSData *data;@property (weak, nonatomic) IBOutlet UIProgressView *progressView;
记住progressView属性是拉出来的,是拉出来的,是拉出来的。接着再拉出下面三个方法,分别添加如下代码:
- (IBAction)startAction:(UIButton *)sender { [self downloadBackground];}- (IBAction)pauseAction:(UIButton *)sender { if (!_task) { return; } [_task cancelByProducingResumeData:^(NSData * _Nullable resumeData) { _data = resumeData; }];}- (IBAction)resumeAction:(UIButton *)sender { if (!_data) { return; }else { _task = [_session downloadTaskWithResumeData:_data]; [_task resume]; }}
解释一下上面的代码,首先把downloadBackground方法移到开始按钮的点击事件里,pauseAction主要就是调用cancelByProducingResumeData方法,用data属性记录resumeData,在resumeAction里重新启动task,注意是调用downloadTaskWithResumeData方法。
做到这里还没有完哦,我们的progressView还没有刷新呢。所以在下载过程调用的回调代理里添加代码:
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite{ NSLog(@"当前进度%f%%",totalBytesWritten * 1.0 / totalBytesExpectedToWrite * 100); //因为这里不是主线程,所以需要回到主线程刷新UI dispatch_async(dispatch_get_main_queue(), ^{ self.progressView.progress = totalBytesWritten * 1.0 / totalBytesExpectedToWrite; });}
现在再运行,你会看到下面的效果:
好了,这就完成了后台下载和断点续传了。代码请点链接,文件夹为后台下载和本地通知
- iOS NSURLSession后台下载和断点续传
- NSURLSession下载和断点续传
- iOS NSURLSession后台下载多个任务,支持断点续传
- iOS - NSURLSession实现断点续传下载
- 从NSURLSession下载和断点续传到NSURLSession使用说明及后台工作流程分析
- iOS开发 - NSURLSession实现断点续传下载
- iOS开发下载、断点续传-NSURLConnection、NSURLSession
- 使用 NSURLSession 开发一个支持后台下载和断点续传的下载工具
- ios断点续传:NSURLSession和NSURLSessionDataTask实现
- IOS断点续传:NSURLSession和NSURLSessionDataTask实现
- iOS断点续传:NSURLSession和NSURLSessionDataTask实现
- NSURLSession下载(断点续传)
- NSURLSession下载之断点续传
- iOS -- 断点续传之 NSURLSession
- ios断点续传:通过NSURLSession实现文件下载功能
- NSURLSession下载文件—断点续传
- NSURLSession下载文件—断点续传
- iOS NSURLSession 实现网络请求-文件下载-上传-后台下载
- SSH中 整合spring和proxool 连接池
- AngularJS基本功能
- Hadoop关于处理大量小文件的问题和解决方法
- soledede--隐马尔可夫模型(HMM)-信道模型
- unity文本自发光效果
- iOS NSURLSession后台下载和断点续传
- Android后台发送短信
- Oracle用户、权限、角色管理
- java日期与时间戳相互转换大全
- 抛物线、导弹线轨迹计算
- 神经网络浅讲:从神经元到深度学习
- 算法_选择排序算法
- Parallel Python(PP)并行计算测试
- MVC单一入口设计思想 session入库 svn与git SAE