• iOS网络学习之“远离NSURLConnection 走进NSURLSession”


      目前,在iOS的开发中,NURLConnection已经成为了过去式,现在的NSURLConnection已经deprected(iOS7之后),取而代之的是NSURLSession。而且AFNetworking 也已经换成了NSURLSession。既然是大势所趋,现总结NSURLSession用法如下:

      首先,是根据简单地按钮实现对应的网络操作:

     1.NSURLSessiion 的GET网络请求:

       要实现网络请求,首先,要准备好URLl 和 必要的参数,而GET最大的特点就是参数是直接的拼接在URL的后面,(路径?参数名=参数值)。然后,就可以通过NSURLSession和NSURLSessionTask愉快的进行GET网络请求了。注意,task要手动开启[task resume];。

    具体使用代码如下:

    - (IBAction)oneAction:(UIButton *)sender {
    
    /**
         *  get请求
         *
         */
    NSString * name=@"jredu";
    NSString * psw=@"123";
    NSURL * url=[NSURLURLWithString:[NSStringstringWithFormat:@"http://localhost/logo.php?userName=%@&pwd=%@",name,psw]];
    
    //>初始化session
    NSURLSession * session=[NSURLSessionsharedSession];
    
    NSURLSessionTask * task=[session dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
    //将返回的二进制数据转为字符串
    NSString * str=[[NSStringalloc] initWithData:data encoding:NSUTF8StringEncoding];
    
    NSLog(@"%@",str);
    
        }];
    
    //开始任务
        [task resume];
    
    }
    

      2.使用NSURLSession进行POST网络请求:

        通过POST方式请求网络,同样是准备好URL,而与GET方式的不同之处:POST时,所需的参数并不是拼接在URL上的,POST的参数通过NSURLRequest传递(NSData);

    准备好参数和URL之后任然是通过NSURLSession和NSURLSessionTask进行网络请求。同样注意:手动开启任务[task resume];

      具体的使用代码如下:

    #pragma mark - post请求
    - (IBAction)twoAction:(UIButton *)sender {
    
    NSString *name=@"codeJerenal";
    NSString *psw=@"123";
    
    NSURL * url =[NSURLURLWithString:@"http://localhost/login_post.php"];
    
    NSString * dataStr=[NSStringstringWithFormat:@"userName=%@&psw=%@",name,psw];
    /** 字符串转data */
    NSData * data=[dataStr dataUsingEncoding:NSUTF8StringEncoding];
    
    /** 初始化可变的请求--设置数据 */
    NSMutableURLRequest * request=[NSMutableURLRequestrequestWithURL:url];
    
        [request setHTTPMethod:@"POST"];
        [request setHTTPBody:data];
    
    /** 初始化session */
    NSURLSession * session=[NSURLSessionsharedSession];
    
    NSURLSessionTask * task=[session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
    
    /** data转字符串调用类方法 */
    NSString *retutnStr=[[NSStringalloc] initWithData:data encoding:NSUTF8StringEncoding];
    NSLog(@"%@",retutnStr);
        }];
    
    //>开始任务
        [task resume];
    }

    3,使用NSURLSession下载:

        要下载数据,首先,要给出要下载的资源的网络路径URL;

       NSURLSession 可以通过NSURLRequest初始化NSURLSession下载,也可以直接使用URL;

       下载成功之后的文件、数据会放在沙盒中的tmp文件中,作为一个临时的文件(返回的location就是其本地的URL),所以在下载成功之后的块中,要及时的将所下载的内容转移到Document中存放(通过NSFileManager)。在移动文件的过程中要注意location是本地的URL 所以,目的地路劲也是URL 应该使用[NSURL fileURLWithString:string];

       在下载完成之后,还会返回一个,NSURLResponse * response,可以通过其中的属性response.suggestedFileame作为文件在本地的命名;

         具体的使用如下所示:

    #pragma mark - 下载数据
    - (IBAction)sessionDownLoadAction:(UIButton *)sender {
    
    //>URL路径
    NSURL * url=[NSURLURLWithString:@"http://localhost/test.zip"];
    
    //>初始化session
    NSURLSession * session=[NSURLSessionsharedSession];
    
    //>定义request
    NSURLRequest * request=[NSURLRequestrequestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicytimeoutInterval:20];
    
    //>定义任务
    NSURLSessionDownloadTask * downLoadTask=[session downloadTaskWithRequest:request completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
    
    //本地沙盒路径
    NSString * path=[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
    
    //文件下载后的存放路径-(转为本地URL使用)(字符串拼接方式,构造本地路径)
    // NSString * fPath=[path stringByAppendingPathComponent:response.suggestedFilename];
    /** 转换 */
    // NSURL * desUrl=[NSURL fileURLWithPath:fPath];
    
    /** 为本地路径准备path (格式化方式,构造本地路径)*/
    NSString * filePath=[NSStringstringWithFormat:@"file://%@/%@",path,response.suggestedFilename];
    
    /** 转为本地的URL */
    NSURL * destinationUrl=[NSURLURLWithString:filePath];
    
    //移动
    NSFileManager * manager =[NSFileManagerdefaultManager];
    
    NSError * error2;
    BOOL isSuccess = [manager moveItemAtURL:location toURL:destinationUrl error:&error2];
    if (isSuccess) {
    
    NSLog(@"成功");
    
            }else{
    
    NSLog(@"失败");
    NSLog(@"%@",error2);
            }
    
        }];
    [task resume];
    }

    4,NSURLSession实现下载的暂停和继续;

       ①:过程中要用到代理方法,而NSURLSession是在初始化的同时设置代理的,并且同时进行下载的设置

    NSURLSessionConfiguration

    参数一 session配置

    参数二设置代理

    参数三设置代理队列

    NSURLSession * session = [NSURLSessionsessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:selfdelegateQueue:[NSOperationQueuemainQueue]];

      ②:通过按钮(或其他的方式)控制下载的暂停继续:

       核心:取消下载任务并保存已经下载的数据

    [self.downTask cancelByProducingResumeData:^(NSData * _Nullable resumeData) {
    self.resumeData=resumeData; }];
    核心: 通过之前保存的已经下载的数据,继续下载
    self.downTask =[self.session downloadTaskWithResumeData:self.resumeData];
    [self.downTask resume];
     
    #pragma mark - 控制起停按钮,点击事件
    - (void) clickAction:(UIButton *)button{
    
        button.selected=!button.selected;
    if (button.selected) {
    
       [self.downTask cancelByProducingResumeData:^(NSData * _Nullable resumeData) {
        /** 全局,用作断点下载存放已经下载的数据*/
        self.resumeData=resumeData;
           }];
    
        }else{
    
    self.downTask =[self.session downloadTaskWithResumeData:self.resumeData];
    
    /** 重新启动任务 */
            [self.downTask resume];
        }
    
    }

    ③:下载过程中的主要代理方法

    #pragma mark - 下载数据的代理方法
    
    /**
     *  代理方法:每次数据下载成功调用方法
     *
     *  @param session                   代理的session
     *  @param downloadTask              代理的task
     *  @param bytesWritten              本次下载的内容长度
     *  @param totalBytesWritten         已经下载的总的内容的长度
     *  @param totalBytesExpectedToWrite 需要下载的文件的总长度
     */
    - (void) URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite{
    
    
    NSLog(@"%lld===%lld=====%lld",bytesWritten,totalBytesWritten,totalBytesExpectedToWrite);
    
    /** 主线程显示下载进度 */
    dispatch_async(dispatch_get_main_queue(), ^{
    if (totalBytesWritten==totalBytesExpectedToWrite) {
    
    _curProgress.frame=CGRectMake(20, 500, 320, 30);
            }else{
    
    _curProgress.frame=CGRectMake(20, 500, totalBytesWritten*(1.0)/totalBytesExpectedToWrite*(1.0)*320, 30);
    /** 随机背景色 */
    _curProgress.backgroundColor=[UIColorcolorWithRed:arc4random_uniform(255)/255.0green:arc4random_uniform(255)/255.0blue:arc4random_uniform(255)/255.0alpha:1];
            }
    
    
        });
    
    }
    /**
     *  代理方法:下载完成时调用--已经下载的文件从临时存放处移动到document中
     *
     *  @param session      代理的session
     *  @param downloadTask 代理的task
     *  @param location     下载文件的临时存放路径
     */
    - (void) URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location{
    
    NSString * documentPath=[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
    
    NSString * filePath =[documentPath stringByAppendingPathComponent:downloadTask.response.suggestedFilename];
    
    NSURL * loaclUrl =[NSURLfileURLWithPath:filePath];
    NSLog(@"%@",loaclUrl);
    
    //移动
    NSError * err;
    BOOL isSuccess=[[NSFileManagerdefaultManager] moveItemAtURL:location toURL:loaclUrl error:&err];
    if (isSuccess) {
    NSLog(@"下载成功");
        }else{
    
    NSLog(@"失败");
    NSLog(@"%@",err);
        }
    
    }
    #pragma mark *** 下载结束
    - (void) URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error{
    
    /**
    如果是其他的原因导致下载失败,程序会走本方法,可以通过
          self.resumeData = error[NSURLSessionDownloadTaskResumeData];
    找到已经下载的数据,解决失败原因之后,可以继续下载
         */
    
    if (error) {
    NSLog(
    @"%@",error);
    }
    else { NSLog(@"成功"); } }
  • 相关阅读:
    java配置文件读取
    简易表单验证
    Enter键提交表单
    background-attachment:fixed应用
    随机生成密钥
    javascript/jquery判断是否为undefined或是null!
    jQuery获取和设置disabled属性、背景图片路径
    $(function(){})里面不能声明定义函数
    CSS浏览器兼容性----Hack
    数组快速排序
  • 原文地址:https://www.cnblogs.com/code-Officer/p/5727247.html
Copyright © 2020-2023  润新知