• iOS网络相关知识总结


    iOS网络相关知识总结

     

    1.关于请求NSURLRequest?

      我们经常讲的GET/POST/PUT等请求是指我们要向服务器发出的NSMutableURLRequest的类型; 我们可以设置RequestURL, HTTPMethod, HTTPHeader, HTTPBody等信息。一般发请求尽量不要使用NSURLRequest,因为它不能设置请求方式、请求超时等(总之什么都不能设置)。通常发请求都使用NSMutableURLRequest,可以进行更多的设置。

     

    补充1:因为NSURL不支持中文,如包含中文,必须转码。

         如果是GET请求,URL是拼接用户输入而来的,极有可能包含中文,在包装成URL前,需对拼接str进行转码。

         POST请求,请求参数拼接成str,然后转成data(中文会自动转码),再赋值给请求体。(如果请求体包含中文,在转成NSData之前最好还是先进行手动转码)

    补充2NSMutableURLRequest.timeoutInterval = 15; 设置请求超时后,如果服务器在15秒后还没有给客户端data,那么边取消本次请求,handerBlock中的data=nil;开始在主线程中执行Block中的代码。

      

    2.关于请求参数?

      GET请求的请求参数需要直接拼接在URL后面,而POST请求的请求参数必须先用&拼接成字符串(也可用NSMutableString拼接),然后转成NSData的形式赋值给请求体。

     

      POST请求参数分以下2种情况:

     

        情况1. HTTP协议规定的标准参数形式

            先用NSString将所有参数用&进行拼接(@"username=123&pwd=123")然后再转化成NSData类型的数据赋值给request.HTTPBody,才能发给服务器。

        例如:

        request.HTTPMethod = @"POST";

        NSData *data = [@"username=123&pwd=123" dataUsingEncoding:NSUTF8StringEncoding];

        request.HTTPBody = data;

     

     

        情况2. 发送json数据给服务器

               在参数非常多,且服务器支持以JSON形式(特殊格式的data)发送请求参数时,那么可以将请求参数存在OC字典/可变字典中,然后使用JSONSerialization的类方法[JSONSerialization dataWithJSONObject:params]; OC字典转化成JSON数据(本质还是NSData),最后赋值给request.HTTPBody发给服务器。

        注意:

            A.必须使用POST才能发送json

            B.必须设置请求头的@"Content-Type"JSONMIME-type:@"application/json",因为默认情况下请求头的Content-Type是所有参数用&拼接在一起的字符串转成的data;

        例如:

        //1.创建POST请求

        NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://abc.com"]];

        request.HTTPMethod = @"POST"; //设置POST

        //2.设置请求头(固定写法)

        [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];

        //3.OC字典保存请求参数

        NSDictionary *params = @{@"goods_name:":@"连衣裙",

                                 @"goods_price":@125,

                                 @"user_ID":@32444455

                                 };

        //4.OC字典转为json(特殊格式NSData

        NSData *jsonData = [NSJSONSerialization dataWithJSONObject:params options:NSJSONWritingPrettyPrinted error:nil];

        //5.赋值给请求体

        request.HTTPBody = jsonData;

      

    3.关于发送网络请求的工具?

      我们向服务器发送这些请求借助的工具就是NSURLConnectionNSURLSessionASIAFN等工具,而这些工具在发送创建好的NSMutableRequest时,可以采用同步或异步2种方式.

     

    4.关于发送网络请求工具的同步or异步?

      同步请求:是在主线程中发送网络请求,这会将主线程卡在[NSURLConnection sendSync];这行代码上,整个UI界面上的所有控件都无法响应用户,这是非常糟糕的。在实际开发中,不管是登录、下载图片/文件都不用同步请求。

      异步请求:开启新的线程进行下载,在主线程的只是开启异步线程代码,而网络请求会在异步线程中发送,故主线程执行完开线程代码后,不会卡顿,会继续执行后面的代码。在实际开发中,所有的网络请求都会使用异步请求,故AFN框架中的所有请求都是异步请求。

     

    5.关于dispatchNSOperation

      dispatchNSOperation都是用来开启异步线程的工具,不过它们也能同步执行(主线程执行)时,只要将待执行的任务添加到主队列中,就会在主线程中执行。用于线程间通讯。

     

     

    --------------------------------------------- 华丽的分割线 -----------------------------------------------

     

     

    1.关于网络请求request的发送工具:NSURLConnectionNSURLSessionASIHTTPRequest(“HTTP终结者”,封装CFNetworking)AFNetworking(封装NSURLConnectionNSURLSession;

     

    2.NSURLConnection的常用方法:

      类方法:[NSURLConnection sendSyncBlock] [NSURLConnection sendAsyncBlock] [NSURLConnection connectionWithRequest: delegate:]

                                                                                                            

    3.NSURLSession的常用方法

      全部总结在另一篇文章《NSURLSession常用方法总结》中,包括所有详细的NSURLSession所有类和方法。

      NSURLSession使用步骤:a.创建session  b.利用session创建dataTask/downloadTask c.session创建的task默认是暂停的,必须调[task resume]开始任务

                                                                                                            

    4.ASIHTTPRequest(“HTTP终结者”,封装CFNetworking)AFNetworking(封装NSURLConnectionNSURLSession

                                                                                                                                                         

    --------------------------------------------- 华丽的分割线 -----------------------------------------------

                                                                                                         

    1.不管是URLConnection还是URLSession,只要是带Block的请求方法(异步请求,开发只用异步方法),如果Block是一次性返回响应的实体data,那么这种方法虽然在异步线程发送,但是由于服务器的data是一次性返回的,返回data的这些方法会瞬间撑爆内存,故只能用于小文件下载,千万不能将一次性返回的data的方法用于下载大文件。

                                                                                                            

    2.不管是URLConnection还是URLSession,只要是带Block的方法,都是直接一次性返回服务器responsedata或者data在沙盒tmp文件夹存储的location.path,故所有带Block的方法是不能监控文件下载进度的。但AFN除外,而AFN将代理方法返回的值传到了主线程的block而已。

     

    3.不管是URLConnection还是URLSession,只要想监控下载进度,就必须通过代理方法(发请求下载都在异步线程,但是代理方法都在主线程调用,方便设置UI),而AFN将代理方法返回的值传到了主线程的block而已。

                                                            

                                                            

    4.URLConnection URLSession在断点续传时的区别:

                                                            

      4.1 URLConnection 断点续传下载大文件:

        //1.创建一个NSInteger属性self.currentLength,用来保存当前已下载的总长度(单位:Bytes)

        //2.didReceiveData方法中,每次保存和计算已下载data长度 self.currentLength += data.length;(单位:Bytes)

        //3.开始和恢复下载都是新建一个连接self.conn,但与普通连接不同的是:必须手动设置request的请求头Range

        //4.暂停下载(其实是取消连接self.conn)即取消连接[self.conn cancel]; self.conn = nil;

        //5.要想断点续传,必须设置HTTP请求的请求头 "Range": "bytes=500-999"

                                                            

        //补充:设置HTTP请求request的请求头Range

        NSString *Range = [NSString stringWithFormat:@"bytes=%zd-",self.currentLength];

        [request setValue:Range forHTTPHeaderField:@"Range"];

                                                            

                                                            

      4.2 URLSession 断点续传下载大文件(再也不用设置恶心的request请求头Range)

     

        //1.创建一个NSDate属性self.resumeData,用来保存downloadTask被取消时留下的遗言resumeData(里面包含下次恢复下载时,从哪个url和哪个Bytes开始下载)

        //2.开始下载需懒加载self.session,然后task = [self.session downloadTaskWithRequest:request]; 再次[task resume];开始下载

        //3.暂停下载(其实是取消task),但必须调用cancelByProducingResumeData-Block,并在block中保存resumeData

        //4.恢复下载(其实是用特殊方法新建任务): task = [self.session downloadTaskWithResumeData:self.resumeData]; [task resume]; self.downloadTask = task; //task保存起来,已便下次取消使用

     

        //补充:第3步暂停下载的关键代码:

        __weak typeof(self) vc = self; //self拥有downloadTask,而downloadTask里面有调用self.resumeData,强引用self

        [vc.downloadTask cancelByProducingResumeData:^(NSData * _Nullable resumeData) {

            vc.resumeData = resumeData; //用于下次恢复时使用

        }];

        vc.downloadTask = nil; //取消后,没必要保留,下次还要创建新的task

     

     

    文章系作者原创,转载请注明出处:http://www.cnblogs.com/stevenwuzheng/p/5619182.html

    如有错误,欢迎随时指正!

  • 相关阅读:
    学习笔记 四边形不等式的模型
    题解 AT2230【Water Distribution】
    题解 CF848C 【Goodbye Souvenir】
    第二届全国大学生算法设计与编程挑战赛(春季赛)正式赛题解&比赛回顾
    积性函数相关学习笔记
    【MySQL】数据库备份
    【SpringMVC】SSM的maven依赖
    【SpringMVC】Jackson解决乱码问题配置
    【SpringMVC】DispatcherServlet与中文过滤器配置
    【Spring】学习笔记008--AOP实现方式
  • 原文地址:https://www.cnblogs.com/stevenwuzheng/p/5619182.html
Copyright © 2020-2023  润新知