美文网首页
NSURLSession

NSURLSession

作者: z4ywzrq | 来源:发表于2017-11-21 18:35 被阅读22次

    前言

    本篇文章来介绍一下 NSURLSession 。
    之前的网络基础架构NSURLConnection,被苹果在iOS9之后宣布弃用,在2013年的WWDC上,Apple揭开了NSURLConnection继任者的面纱:NSURLSession。

    NSURLSession 介绍

    1. NSURLSession 支持 http2.0 协议。

    2. 与NSURLConnection相比,NSURLSession最直接的改善就是提供了配置每个会话的缓存,协议,cookie和证书政策(credential policies)。这使得框架的网络基础架构和部分应用程序独立工作,而不会互相干扰。每一个NSURLSession对象都是根据一个NSURLSessionConfiguration初始化的,该NSURLSessionConfiguration指定了上面提到的政策,以及一系列为了提高移动设备性能而专门添加的新选项。

    3. NSURLSession针对下载/上传等复杂的网络操作提供了专门的解决方案,针对普通、上传和下载分别对应三种不同的网络请求任务:NSURLSessionDataTask, NSURLSessionUploadTask和NSURLSessionDownloadTask。创建的task都是挂起状态,需要调用resume方法才能执行。


      NSURLSessionTask.png

    NSURLSessionDataTask,可以用来处理一般的网络请求,如 GET | POST 请求等。
    NSURLSessionDataTask 有一个子类为 NSURLSessionUploadTask,主要用于处理上传请求。
    NSURLSessionDownloadTask,主要用于处理下载请求。

    NSURLSession 使用

    NSURLSessionDataTask 发送 GET 请求

    //请求链接
     NSString * urlStr = @"https://api.douban.com/v2/book/1220562";
    
     //创建 NSURLSession 对象
     NSURLSession * session = [NSURLSession sharedSession];
     
     /**
      创建 Data Task 请求
      completionHandler  完成之后的回调(成功或失败)
      @param data     返回的数据(响应体)
      @param response 响应头
      @param error    错误信息
      */
        
        NSURLSessionDataTask * dataTask = [session dataTaskWithURL:[NSURL URLWithString:urlStr] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
            NSDictionary * dataDict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];
            NSLog(@"--- %@ %@  %@", dataDict, NSStringFromClass([response class]), error);
    
        }];
        //执行data task
        [dataTask resume];
    

    NSURLSessionDataTask 发送 POST 请求

        NSURLSession * session = [NSURLSession sharedSession];
        NSString * urlStr = @"https://api.weibo.com/2/statuses/update.json";
    
        //创建可变请求对象
        NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlStr]];
        //设置请求类型 post
        request.HTTPMethod = @"POST";
        //设置请求体
        request.HTTPBody = [@"status=123&access_token=123" dataUsingEncoding:NSUTF8StringEncoding];
        //创建请求 task
        NSURLSessionDataTask * dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
            //解析返回数据
            NSDictionary * dataDict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];
            NSLog(@"--- %@ %@  %@", dataDict, NSStringFromClass([response class]), error);
            
        }];
        //执行data task
        [dataTask resume];
    
    
    

    NSURLSessionDownloadTask 下载内容

    //下面的例子,使用NSURLSessionDownloadTask来下载一张图片
        
        NSURLSession * session = [NSURLSession sharedSession];
        //图片链接
        NSString * urlStr = @"https://img.haomeiwen.com/i288548/8240c430a7526d6a.png";
        NSURLSessionDownloadTask * downloadTask = [session downloadTaskWithURL:[NSURL URLWithString:urlStr] completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
    
            //下载完成,下载的内容是先保存在沙盒的Tmp文件夹中,location文件保存的路径
            //在tmp文件中只是短暂的保存,很快就会被清除
            //要想保存下来,可以移动到别的文件夹中,下面是将文件保存到Caches文件夹中
            
            NSString *filePath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject]
                                  stringByAppendingPathComponent:response.suggestedFilename];
            
            [[NSFileManager defaultManager] moveItemAtURL:location toURL:[NSURL fileURLWithPath:filePath] error:nil];
            
        }];
        [downloadTask resume];
    
    

    使用代理方法获取数据

        //创建获取数据任务,用来获取图片数据
        NSURLSessionConfiguration * configuration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:@"com.myapp.networking.getdata"];
        NSURLSession * session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil];
    
        //图片链接
        NSString * urlStr = @"http://f.hiphotos.baidu.com/image/pic/item/1f178a82b9014a903ba25d77a0773912b21bee58.jpg";
        NSURLSessionDataTask * dataTask = [session dataTaskWithURL:[NSURL URLWithString:urlStr]];
        [dataTask resume];
    
    
    -(void)URLSession:(NSURLSession *)session dataTask:(nonnull NSURLSessionDataTask *)dataTask
    didReceiveResponse:(nonnull NSURLResponse *)response
    completionHandler:(nonnull void (^)(NSURLSessionResponseDisposition))completionHandler {
        //开始接收数据
        self.dataM = [NSMutableData data];
        //必须告诉系统是否接收服务器返回的数据
        completionHandler(NSURLSessionResponseAllow);
    }
    -(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data {
        //拼接服务器返回的数据
        [self.dataM appendData:data];
    }
    -(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
    
        //获取到全部数据
        dispatch_async(dispatch_get_main_queue(), ^{
            self.imgView.image = [UIImage imageWithData:self.dataM];
        });
    }
    
    

    下载任务NSURLSessionDownloadTask,代理方法 NSURLSessionDownloadDelegate

        NSURLSessionConfiguration *backgroundConfiguration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier: @"com.myapp.networking.background"];
        NSOperationQueue *operationQueue = [NSOperationQueue mainQueue];
        NSURLSession *backgroundSession = [NSURLSession sessionWithConfiguration:backgroundConfiguration delegate:self delegateQueue:operationQueue];
        NSURL *url = [NSURL URLWithString:@"http://f.hiphotos.baidu.com/image/pic/item/1f178a82b9014a903ba25d77a0773912b21bee58.jpg"];
        NSURLSessionDownloadTask *downloadTask = [backgroundSession downloadTaskWithURL:url];
        [downloadTask resume];
    
    
    //代理方法
    - (void)URLSession:(NSURLSession *)session
          downloadTask:(NSURLSessionDownloadTask *)downloadTask
          didWriteData:(int64_t)bytesWritten
     totalBytesWritten:(int64_t)totalBytesWritten
    totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite
    {
        NSLog(@"Session %@ download task %@ wrote an additional %lld bytes (total %lld bytes) out of an expected %lld bytes.\n", session, downloadTask, bytesWritten, totalBytesWritten, totalBytesExpectedToWrite);
    }
    
    - (void)URLSession:(NSURLSession *)session
          downloadTask:(NSURLSessionDownloadTask *)downloadTask
     didResumeAtOffset:(int64_t)fileOffset
    expectedTotalBytes:(int64_t)expectedTotalBytes
    {
        NSLog(@"Session %@ download task %@ resumed at offset %lld bytes out of an expected %lld bytes.\n", session, downloadTask, fileOffset, expectedTotalBytes);
    }
    
    - (void)URLSession:(NSURLSession *)session
          downloadTask:(NSURLSessionDownloadTask *)downloadTask
    didFinishDownloadingToURL:(NSURL *)location
    {
        NSLog(@"Session %@ download task %@ finished downloading to URL %@\n", session, downloadTask, location);
        
        // Perform the completion handler for the current session
        //self.completionHandlers[session.configuration.identifier]();
        
        // Open the downloaded file for reading
        NSError *readError = nil;
        NSFileHandle *fileHandle = [NSFileHandle fileHandleForReadingFromURL:location error:&readError];
        // ...
        
        // Move the file to a new URL
        NSFileManager *fileManager = [NSFileManager defaultManager];
        NSURL *cacheDirectory = [[fileManager URLsForDirectory:NSCachesDirectory inDomains:NSUserDomainMask] firstObject];
        NSError *moveError = nil;
        if ([fileManager moveItemAtURL:location toURL:cacheDirectory error:&moveError]) {
            // ...
        }
    }
    
    

    Reference

    https://developer.apple.com/documentation/foundation/urlsession
    https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/URLLoadingSystem/URLLoadingSystem.html#//apple_ref/doc/uid/10000165i

    相关文章

      网友评论

          本文标题:NSURLSession

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