美文网首页
NSURLSession

NSURLSession

作者: MeteorCode | 来源:发表于2017-11-06 19:01 被阅读2次
    • NSURLConnection在 iOS9 被宣布弃用,逐渐被 NSURLSession 替代;
    • NSURLSession 、 NSURLSessionConfiguration 、NSURLSessionTask 常用三个类;
    • AFNetWorking 从2.0版本开始,就是在 NSURLSession 的基础上封装的;

    NSURLSession

    使用:
    1 - 通过NSURLSession的实例创建 task 任务;
    2 - resume 执行 task 任务

    NSURLSessionTask

    可以理解为任务: 数据请求任务,下载任务,上传任务等;

    • NSURLSessionTask 的子类
    NSURLSessionDataTask   数据请求
    NSURLSessionUploadTask  上传
    NSURLSessionDownloadTask  下载
    

    NSURLSessionDataTask 数据请求任务

    dataTask 是执行数据请求相关的任务,但也可以用来执行上传和下载相关的任务,是我们使用最多的task;

    • block 形式
      简单的get请求:
      如果返回值比较简单,则用这种简单的block方式。
    NSURLSession *session = [NSURLSession sharedSession]; //单例创建session对象
    NSURL *url = [NSURL URLWithString: "http://www.baidu.com/signin?username=13800138008&password=123456"];
    // 初始化task
    NSURLSessionTask *task = [session dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError error) { 
       //数据处理
     NSLog(@"%@", [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil]);
    }];
    [task resume]; // 启动任务 :所有类型的task都要调用resume方法才会开始进行请求
    

    简单的post请求:

    NSURLSession *session = [NSURLSession sharedSession];
    
    NSURL *url = [NSURL URLWithString: @"http://www.baidu.com/signin"];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    request.HTTPMethod = @"POST"; //post请求
    request.HTTPBody = [@"username=13800138008&password=123456" dataUsingEncoding: 
    NSUTF8StringEncoding];
    
    // 通过request初始化task
    NSURLSessionTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { 
        NSLog(@"%@", [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil]); 
    }];
    [task resume];
    

    get 和 post 的区别:

    请求方式 初始化task 参数方式
    get url 参数拼接在 urlString 后面
    post request 将参数通过 utf8 编码,然后放在request 的body中
    • NSURLSessionDataDelegate 代理形式
      简单的数据可以用 block 的方式进行处理,如果返回的数据比较复杂,或者相对数据进一步处理,则使用 NSURLSession 的 delegate。
      delegate 分几个阶段 : 响应,接收数据,请求完成;
      以get为例:
    //创建session: session的delegate属性是只读的;delegateQueue 表示代理方法在哪个队列中执行;
    [NSURLSessionConfiguration defaultSessionConfiguration] 表示默认配置
    
    NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[[NSOperationQueue alloc] init]];
    
    // 创建任务
    NSURLSessionDataTask *task = [session dataTaskWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.baidu.com/login?userName=13800138008&password=123456"]]];
    
    [task resume];  // 启动任务
    

    delegate方法:

    // 接收到服务器的响应
    - (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler {
    
        completionHandler(NSURLSessionResponseAllow); // 允许处理服务器的响应,才会继续接收服务器返回的数据
    }
    
    // 接收服务器的数据(会调用多次)
    - (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data {
        // 处理接收到的数据
    }
    
    // 请求完成
    - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task 
       didCompleteWithError:(NSError *)error {
        // 请求完成,处理成功的数据或者拿到错误的error值
    }
    

    NSURLSessionDownloadTask 下载任务

    和 一样,有通过 url 和 request 两种方式来初始化 session;

    • 通过 url 来初始化,bloc形式:
    SURLSession *session = [NSURLSession sharedSession];
    NSURL *url = [NSURL URLWithString:@"http://www.baidu.com/source/icon/my.png"] ;
    
    NSURLSessionDownloadTask *task = [session downloadTaskWithURL:url completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error) {
    
        // 返回的  location 是沙盒中tmp文件夹下的一个临时url,文件下载后会存到这个位置,由于tmp中的文件随时可能被删除,所以我们需要自己需要把下载的文件挪到需要的地方
        NSString *path = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask,YES) lastObject] stringByAppendingPathComponent: response.suggestedFilename];
    
        // 移动文件; response.suggestedFilename 是 url 中的最后一部分,如:my.png
        [[NSFileManager defaultManager] moveItemAtURL:location toURL:[NSURL fileURLWithPath:path] 
          error:nil];
    }];
    [task resume]; // 启动任务
    
    • NSURLSessionDownloadDelegate 代理的形式:
    // 每次写入调用(会调用多次)
    - (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite {
       // 可在这里通过已写入的长度和总长度算出下载进度
       CGFloat progress = 1.0 * totalBytesWritten / totalBytesExpectedToWrite;
    NSLog(@"%f",progress);
    }
    
    // 下载完成调用
    - (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location {
    
        // location 还是一个临时路径,需要自己挪到需要的路径(caches下面)
        NSString *filePath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask,YES) lastObject] stringByAppendingPathComponent:downloadTask.response.suggestedFilename];
       //移动文件
        [[NSFileManager defaultManager] moveItemAtURL:location toURL:[NSURL fileURLWithPath:filePath] error:nil];
    }
    
    // 任务完成调用
    - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
    
    }
    
    • 断点下载
      这种断点下载只支持应用内断点,如果程序在下载过程中途关闭,则不能恢复下载。
    // 取消下载 :用这种方式取消下载,可以得到将来用来恢复的数据,保存起来
    [self.task cancelByProducingResumeData:^(NSData *resumeData) {
        self.resumeData = resumeData; //保存数据
    }];
    
    // 下载失败导致的下载中断会进入此协议方法,也可以得到用来恢复的数据
    - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
        // 保存恢复数据
        self.resumeData = error.userInfo[NSURLSessionDownloadTaskResumeData];
    }
    
    // 恢复下载时接过保存的恢复数据
    self.task = [self.session downloadTaskWithResumeData:self.resumeData];
    [self.task resume];  // 启动任务
    

    NSURLSessionUploadTask 上传任务

    上传方式有两种:
    1 -

    NSURLSessionUploadTask *task = [[NSURLSession sharedSession] uploadTaskWithRequest:request fromFile:fileName completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
    }];
    

    2 - post 方法: body 参数需要填写request的请求体(http协议规定格式的大长串)
    出于安全考虑,用这种方法比较多;

    [self.session uploadTaskWithRequest:request fromData: body completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
        NSLog(@"%@", [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil]);
     }];
    

    每个task 自身有都拥有下面几个方法

    - (void)suspend;  暂停当前任务
    - (void)resume;   启动任务,也可以唤醒suspend状态的任务
    - (void)cancel;   取消当前的任务,也可以向处于suspend状态的任务发送cancel消息,任务如果被取消便不能再恢复到之前的状态。
    

    NSURLSessionConfiguration 配置

    • 默认配置
    NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration]; 
    config.timeoutIntervalForRequest = 10; // 超时时间
    config.allowsCellularAccess = YES; // 是否允许使用蜂窝网络(后台传输不适用)
    
    • task有三种配置
    + (NSURLSessionConfiguration *)defaultSessionConfiguration;   默认模式,会将缓存存储在磁盘上
    + (NSURLSessionConfiguration *)ephemeralSessionConfiguration;  瞬时会话模式,不会创建持久性存储的缓存
    + (NSURLSessionConfiguration *)backgroundSessionConfigurationWithIdentifier:(NSString *)identifier;后台会话模式,允许程序在后台进行上传下载工作
    

    相关文章

      网友评论

          本文标题:NSURLSession

          本文链接:https://www.haomeiwen.com/subject/zdeapxtx.html