zoukankan      html  css  js  c++  java
  • (一二七)NSURLSession的基本用法 下载与数据获取

    简介

    NSURLSession是苹果官方提供的一系列网络接口库,使用他们可以轻松实现下载和数据获取等任务。在上一篇文章中,我们介绍了使用NSURLConnection下载文件和断点续传的功能,实现起来比较麻烦,对于文件的操作也比较繁琐,如果使用NSURLSession,这一切都将变得极为容易。

    用法

    • 数据请求
      1.获取URLSession单例对象,并利用该对象创建一个dataTask,使用结构体回调。
      这段代码从网站上抓取JSON数组,解析为OC字典。

      NSURLSession *session = [NSURLSession sharedSession];
      NSURLSessionDataTask *task = [session dataTaskWithURL:[NSURL URLWithString:@"http://www.soulghost.com/randompk/storeTest/baseRandom.php?type=attack"] completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
      NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil];
      NSLog(@"%@",dict);
      }];

      2.开启任务
      所有任务在创建时都是暂停的,应该手动启动。

      [task resume];
    • 小文件下载
      1.获取URLSession单例对象,创建一个downloadTask。

      • 注意此任务默认将文件下载到tmp文件夹,并且在下载结束后如果不处理会秒删,一般的做法是把它移动到Document或者Caches中,当下载结束后会调用结构体,在结构体里处理文件即可。
      • 通过NSFileManager可以实现文件的复制、移动操作,回调的location是tmp中刚刚下载的文件的URL。

        NSURLSession *session = [NSURLSession sharedSession];
        NSURLSessionDownloadTask *task = [session downloadTaskWithURL:[NSURL URLWithString:@"http://127.0.0.1/lesson1/nav.dmg"] completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error) {
        // 临时下载到tmp,必须及时处理,否则会被系统秒删。
        // 应该将临时文件移动到Caches文件夹
        NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
        // 可以使用建议的文件名,与服务端一致
        NSString *file = [path stringByAppendingPathComponent:response.suggestedFilename];
        // 移动文件
        NSFileManager *mgr = [NSFileManager defaultManager];
        [mgr moveItemAtPath:location.path toPath:file error:nil];
        }];

        2.开启任务
        所有任务在创建时都是暂停的,应该手动启动。

        [task resume];
    • 大文件下载
      大文件常常需要获取进度,这就需要设置代理,而不是用block回调。
      1.遵循代理方法,创建两个成员,一个用于指向下载任务对象,另一个用于保存断点数据。

      @interface ViewController () <NSURLSessionDownloadDelegate>
      @property (nonatomic, strong) NSURLSessionDownloadTask *task;
      @property (nonatomic, strong) NSData *resumeData;
      @end

      2.获取URLSession单例,创建下载任务,注意使用的方法与前面不同。

      • 不要忘了保存task。
      NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];
      NSURLSessionDownloadTask *task = [session downloadTaskWithURL:[NSURL URLWithString:@"http://127.0.0.1/lesson1/nav.dmg"] ];
      [task resume];
      _task = task;

      3.下载过程中会调用下面的代理方法,指示此次下载的字节数,一共下载的字节数与总字节数。

      - (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite{
      NSLog(@"写入量:%lld 下载进度:%f",bytesWritten,(double)totalBytesWritten/totalBytesExpectedToWrite);
      }

      4.下载结束后回调用下面的代理方法,从中同样要移动文件,只是如果要想拿到响应体response的suggestedFilename,需要通过downloadTask。

      - (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location{
      NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
      // 可以使用建议的文件名,与服务端一致
      NSString *file = [path stringByAppendingPathComponent:downloadTask.response.suggestedFilename];
      // 移动文件
      NSFileManager *mgr = [NSFileManager defaultManager];
      [mgr moveItemAtPath:location.path toPath:file error:nil];
      
      [self.btn setTitle:@"Start" forState:UIControlStateNormal];
      }

      5.如果要暂停下载,调用下面的方法,通过回调结构体拿到断点数据,保存在我们之前创建的成员中以便恢复。

      • 注意用weakSelf避免循环引用。
      • 任务结束后就无效了,应该让指针指向nil来释放内存。
      __weak typeof(self) weakSelf = self;
      [self.task cancelByProducingResumeData:^(NSData *resumeData) {
      // resumeData内部包含了下次继续下载的开始位置
      weakSelf.resumeData = resumeData;
      weakSelf.task = nil;
      }];

      6.要恢复下载数据很容易,只需要通过断点创建任务即可。

      • 注意清空resumeData。
      NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];
      // 传入上次暂停下载返回的数据
      NSURLSessionDownloadTask *task = [session downloadTaskWithResumeData:self.resumeData];
      [task resume];
      _task = task;
      _resumeData = nil;
    • 断点续传开始时会调用下面的代理方法说明文件信息。

      - (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffset expectedTotalBytes:(int64_t)expectedTotalBytes{
      }
  • 相关阅读:
    【原】Coursera—Andrew Ng机器学习—课程笔记 Lecture 15—Anomaly Detection异常检测
    【原】Coursera—Andrew Ng机器学习—课程笔记 Lecture 14—Dimensionality Reduction 降维
    【原】Coursera—Andrew Ng机器学习—课程笔记 Lecture 13—Clustering 聚类
    【原】Coursera—Andrew Ng机器学习—课程笔记 Lecture 12—Support Vector Machines 支持向量机
    【原】机器学习公开课 目录(课程笔记、测验习题答案、编程作业源码)...持续更新...
    【原】Coursera—Andrew Ng机器学习—Week 11 习题—Photo OCR
    【原】Coursera—Andrew Ng机器学习—Week 10 习题—大规模机器学习
    【原】Coursera—Andrew Ng机器学习—Week 9 习题—异常检测
    【原】Coursera—Andrew Ng机器学习—Week 8 习题—聚类 和 降维
    【原】Coursera—Andrew Ng机器学习—Week 7 习题—支持向量机SVM
  • 原文地址:https://www.cnblogs.com/aiwz/p/6154027.html
Copyright © 2011-2022 走看看