iOS 原生网络请求 NSURLSession 和 NSMutableURLRequest应用示例

大部分的iOS开发在刚开始接触网络请求时,应该都是用的AFNetworking这个在iOS界扛把子的框架来做的吧,但你们知道这个框架在做网络请求的时候都做了什么吗。这篇文章会从系统原生的网络请求来揭示网络请求的本质,以后如果有时间会简单解析AFNetworking的源码。

原生网络请求分为三个部分:

  1. NSMutableURLRequest请求类

先来一张网络请求的抓包信息图:

iOS 原生网络请求 NSURLSession 和 NSMutableURLRequest应用示例_第1张图片
网络请求抓包.png

图片来自: 编程小翁

上图便是一个完整的网络请求的抓包示意图,NSMutableURLRequest这个类就是管理者上半部分的所有信息,如下图框出来的部分:

iOS 原生网络请求 NSURLSession 和 NSMutableURLRequest应用示例_第2张图片
网络请求抓包.png

图片来自: 编程小翁

其实就是网络请求中的HTTPHeaderField信息。我们来一一细说其中作用(其中着重看Content-Type、Cookie、Content-Length,因为我们配置这些就行了。另外还有一个重要字段图中没有,那就是传输的内容HTTPBody代码中会讲到)。

POST:这个可以是GET或者别的请求方式,这里放的是URL后半段
Host:这里是主机地址,Host和POST字段拼接起来就是一个完整的URL
Accept:这个网络请求发送的数据的格式说明:如Accept:text/html,这说明这个网络请求发送的
       是HTML格式的数据。图中的Accept:*/* 为通用格式。
Content-Type:这个字段表明数据发送方(也就是我们客户端)想要接收的数据格式,一下有一个格式
       对照表的截图。
Connection:网络请求连接的方式,这个我们不用设置。
Cookie:我们只能从服务器得到这个字段,用于维持服务端会话状态,也可以用来做接口验证,类似
        token这样的。并且在iOS中,如果请求中cookie字段有值,苹果会自动帮我们保存下来,
        代码中会讲。
Accept-Language:表明可以接收什么文字,zh-cn表示中文。
Content-Length:表示传输内容的长度。
Accept-Encoding:表示客户端支持的编码格式,这个不用我们配置。
User-Agent:这个就像是一个网名,随便写都可以,一般不做配置。

创建一个NSMutableURLRequest

/** 创建request对象 */
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]];
    
    /** 这个操作就是检测cookie的方法,我们的系统会自动将cookie保存下来,通过下面的方法可以检测出来,如果服务器要求我们同步cookie,则在request中设置Cookie的值 */
    NSHTTPCookieStorage *cookieJar = [NSHTTPCookieStorage sharedHTTPCookieStorage];
    for (NSHTTPCookie *cookie in [cookieJar cookies]) {
        
        if (cookie != nil) {
            NSDictionary *headers=[NSHTTPCookie requestHeaderFieldsWithCookies:[cookieJar cookies]];
            [request setValue:[headers objectForKey:@"Cookie"] forHTTPHeaderField:@"Cookie"];
        }
    }
    
    
    /**
         如果传入参数不为空,则为POST请求
         如果传入的参数为nil,则为GET请求
     */
    if (parameters != nil && parameters.count > 0) {
        
        /** 传入的参数为一个字典,我们需要把字典转化为一个以"&"分隔的字符串,再将字符串转化为data,最后设置到HTTPBody里面去 */
        NSData *bodyData = [self getDataFromParameters:parameters];
        
        [request setHTTPMethod:@"POST"];
        [request setHTTPBody:bodyData];
        [request setValue:[NSString stringWithFormat:@"%lld",(long long)bodyData.length] forHTTPHeaderField:@"Content-Length"];
        
        /** 这个可以固定 */
        [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
    }
    
    /** 设置请求时间 */
    request.timeoutInterval = 8.0;
  1. NSURLSession会话类
  2. NSURLSessionDataTask会话任务类
   把这两个放到一起讲,是因为这两个很简单。一个request请求需要一个会话来启动和管理,但我们仅仅只需要一个创建一个对象就行了
    /** 创建会话对象 */
    NSURLSession *session = [NSURLSession sharedSession];

    最后我们需要把会话对象用来创建一个任务对象就完成了:
    /** 创建会话任务,并用会话对象启动请求对象 */
    NSURLSessionDataTask *sessionDataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
    }];

    注意一点:会话任务需要手动启动
    /** 开始任务 */
    [sessionDataTask resume];

至此,系统原生的网络请求就完成了。
demo地址

你可能感兴趣的:(iOS 原生网络请求 NSURLSession 和 NSMutableURLRequest应用示例)