iOS-网络请求的简介(NSURLConnection/NSURLSession)

一、HTTP的请求方法

  • GET、POST、OPTIONS、HEAD、PUT、DELETE、TRACE、CONNECT、PATCH
  • 最常用的是GET和POST

二、GET和POST对比

  • GET:
    2.1 在请求URL后面以?的形式跟上发给服务器的参数,多个参数之间用&隔开
    2.2 由于浏览器和服务器对URL长度有限制,因此在URL后面附带的参数是有限制的,通常不能超过1KB
  • POST:
    2.3 发给服务器的参数全部放在请求体中
    2.4 理论上,POST传递的数据量没有限制

三、GET和POST的选择

  • 如果要传递大量数据,比如文件上传,只能用POST请求
  • GET的安全性比POST要差些,如果包含机密\敏感信息,建议用POST
    p如果仅仅是索取数据(数据查询),建议使用GET
    p如果是增加、修改、删除数据,建议使用POST

四、iOS中Http请求的方案

苹果原生(自带)

  • NSURLConnection:用法简单,最古老最经典最直接的一种方案【坑比较多】
  • NSURLSession:功能比NSURLConnection更加强大,苹果目前比较推荐使用这种技术【2013推出,iOS7开始出的技术】
  • CFNetwork:NSURL*的底层,纯C语言

第三方框架

  • ASIHttpRequest:外号“HTTP终结者”,功能极其强大,可惜早已停止更新
  • AFNetworking:简单易用,提供了基本够用的常用功能,维护和使用者多
  • MKNetworkKit:简单易用,产自三哥的故乡印度,维护和使用者少

五、NSURLConnection的简单使用

参考网址:http://www.jianshu.com/p/f291ee58c012

5.1、NSURLConnection同步操作

sendSynchronousRequest:阻塞式的方法,会卡住线程

//1.确定请求路径
 NSString *url = @"http://192.168.5.108:8668/jeeplus";
    //中文编码
    NSString *urlPath = [url stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
    //URL
    NSURL *URL = [NSURL URLWithString:urlPath];
    
    //2.创建一个请求对象
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL];
    //超时3S
    request.timeoutInterval = 3;
    //请求方式
    request.HTTPMethod = @"GET";
    [request setValue:@"Upgrade" forHTTPHeaderField:@"Connection"];
    [request setValue:@"websocket" forHTTPHeaderField:@"Upgrade"];
    [request setValue:@"13" forHTTPHeaderField:@"Sec-WebSocket-Version"];
    [request setValue:[self ret16bitString] forHTTPHeaderField:@"Sec-WebSocket-Key"];
//2.2设置请求体
    request.HTTPBody = [@"username=520it&pwd=520it" dataUsingEncoding:NSUTF8StringEncoding];


//同步
    //3.把请求发送给服务器
    NSURLResponse * response;
    NSError * error;
    /*
     第一个参数:请求对象
     第二个参数:响应头信息,当该方法执行完毕之后,该参数被赋值
     第三个参数:错误信息,如果请求失败,则error有值
     */
    NSData * backData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
    if (error) {
        NSLog(@"【握手请求】error : %@",[error localizedDescription]);
    }else{
        NSLog(@"【握手请求】response : %@",response);
        NSLog(@"【握手请求】backData : %@",[[NSString alloc]initWithData:backData encoding:NSUTF8StringEncoding]);
        NSDictionary *dictData = [NSJSONSerialization JSONObjectWithData:backData options:kNilOptions error:nil];
        NSLog(@"【握手请求】msg is %@",[dictData objectForKey:@"msg"]);
    }

5.2、NSURLConnection异步操作

sendAsynchronousRequest:不会卡住当前线程,网络请求任务是异步执行的

    //1.确定请求路径
    NSString *url = @"http://192.168.5.108:8668/jeeplus";
    //中文编码
    NSString *urlPath = [url stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
    //URL
    NSURL *URL = [NSURL URLWithString:urlPath];

    //2.创建一个请求对象
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    //2.1更改请求方法
    request.HTTPMethod = @"POST";
    //2.2设置请求体
    request.HTTPBody = [@"username=520it&pwd=520it" dataUsingEncoding:NSUTF8StringEncoding];

    //3.把请求发送给服务器,发送一个异步请求
    /*
     第一个参数:请求对象
     第二个参数:回调方法在哪个线程中执行,如果是主队列则block在主线程中执行,非主队列则在子线程中执行
     第三个参数:completionHandlerBlock块:接受到响应的时候执行该block中的代码
        response:响应头信息
        data:响应体
        connectionError:错误信息,如果请求失败,那么该参数有值
     */
    NSOperationQueue * queue = [NSOperationQueue mainQueue];
    [NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse * __nullable response, NSData * __nullable data, NSError * __nullable connectionError) {
        //4.解析服务器返回的数据
        NSString *str = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
        //转换并打印响应头信息
        NSHTTPURLResponse *r = (NSHTTPURLResponse *)response;
        NSLog(@"--%zd---%@--",r.statusCode,r.allHeaderFields);
    }];

六、NSURLSession的简介与使用

参考网址:http://www.jianshu.com/p/02a5a896c9ed
http://www.cocoachina.com/ios/20160601/16544.html
http://www.cnblogs.com/wendingding/p/5168772.html
http://www.jianshu.com/p/fafc67475c73

6.1、知识点

简介:在iOS9.0之后,以前使用的NSURLConnection过期,苹果推荐使用NSURLSession来替换NSURLConnection完成网路请求相关操作。

NSURLSession
NSURLSessionConfiguration
NSURLSessionTask的三个子类:
NSURLSessionDataTask //一般的get、post等请求
NSURLSessionUploadTask // 用于上传文件或者数据量比较大的请求
NSURLSessionDownloadTask //用于下载文件或者数据量比较大的请求

task的三个函数

  • (void)suspend;//暂停
  • (void)resume;//开始或者恢复
  • (void)cancel;//关闭任务

6.2、NSURLSessionConfiguration

简单地说,就是session的配置信息.

#方式一:采用苹果提供的共享session,不做任何修改
    NSURLSession *sharedSession = [NSURLSession sharedSession];
#方式二:通过NSURLSessionConfiguration方式配置不同的NSURLSession
    // 构造NSURLSessionConfiguration
    NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
//也可以通过NSURLSessionConfiguration统一设置超时时间、请求头等信息
    //设置请求超时为10秒钟
    configuration.timeoutIntervalForRequest = 10;
    //在蜂窝网络情况下是否继续请求(上传或下载)
    configuration.allowsCellularAccess = NO;
    //配置请求头
    configuration.HTTPAdditionalHeaders =@{@"Content-Encoding":@"gzip"};
// 构造NSURLSession,网络会话;
    NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration];

6.3、最简单的GET与POST的demo

GET

使用NSURLSession发送GET请求的方法和NSURLConnection类似,整个过程如下:
1)确定请求路径(一般由公司的后台开发人员以接口文档的方式提供),GET请求参数直接跟在URL后面
2)创建请求对象(默认包含了请求头和请求方法【GET】),此步骤可以省略
3)创建会话对象(NSURLSession)
4)根据会话对象创建请求任务(NSURLSessionDataTask)
5)执行Task
6)当得到服务器返回的响应后,解析数据(XML|JSON|HTTP)

发送GET的方法一:dataTaskWithRequest
-(void)get1
{
    //对请求路径的说明
    //http://120.25.226.186:32812/login?username=520it&pwd=520&type=JSON
    //协议头+主机地址+接口名称+?+参数1&参数2&参数3
    //协议头(http://)+主机地址(120.25.226.186:32812)+接口名称(login)+?+参数1(username=520it)&参数2(pwd=520)&参数3(type=JSON)
    //GET请求,直接把请求参数跟在URL的后面以?隔开,多个参数之间以&符号拼接
    
    //1.确定请求路径
    NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/login?username=520it&pwd=520it&type=JSON"];
    
    //2.创建请求对象
    //请求对象内部默认已经包含了请求头和请求方法(GET)
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    
    //3.获得会话对象
    NSURLSession *session = [NSURLSession sharedSession];
      
    //4.根据会话对象创建一个Task(发送请求)
    /*
     第一个参数:请求对象
     第二个参数:completionHandler回调(请求完成【成功|失败】的回调)
               data:响应体信息(期望的数据)
               response:响应头信息,主要是对服务器端的描述
               error:错误信息,如果请求失败,则error有值
     */
    NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        if (error == nil) {
            //6.解析服务器返回的数据
            //说明:(此处返回的数据是JSON格式的,因此使用NSJSONSerialization进行反序列化处理)
            NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
            NSLog(@"%@",dict);
        }
    }];
    
    //5.执行任务
    [dataTask resume];
}
发送GET方法二:dataTaskWithURL
-(void)get2
{
    //1.确定请求路径
    NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/login?username=520it&pwd=520it&type=JSON"];
    
    //2.获得会话对象
    NSURLSession *session = [NSURLSession sharedSession];
    
    //3.根据会话对象创建一个Task(发送请求)
    /*
     第一个参数:请求路径
     第二个参数:completionHandler回调(请求完成【成功|失败】的回调)
               data:响应体信息(期望的数据)
               response:响应头信息,主要是对服务器端的描述
               error:错误信息,如果请求失败,则error有值
     注意:
        1)该方法内部会自动将请求路径包装成一个请求对象,该请求对象默认包含了请求头信息和请求方法(GET)
        2)如果要发送的是POST请求,则不能使用该方法
     */
    NSURLSessionDataTask *dataTask = [session dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        //5.解析数据
        NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
        NSLog(@"%@",dict);
    }];
    
    //4.执行任务
    [dataTask resume];
}

POST

使用NSURLSession发送POST请求的方法和NSURLConnection类似,整个过程如下:
1)确定请求路径(一般由公司的后台开发人员以接口文档的方式提供)
2)创建可变的请求对象(因为需要修改),此步骤不可以省略
3)修改请求方法为POST
4)设置请求体,把参数转换为二进制数据并设置请求体
5)创建会话对象(NSURLSession)
6)根据会话对象创建请求任务(NSURLSessionDataTask)
7)执行Task
8)当得到服务器返回的响应后,解析数据(XML|JSON|HTTP)

由于POST需要修改“请求对象”参数,所以只能dataTaskWithRequest
-(void)post
{
    //对请求路径的说明
    //http://120.25.226.186:32812/login
    //协议头+主机地址+接口名称
    //协议头(http://)+主机地址(120.25.226.186:32812)+接口名称(login)
    //POST请求需要修改请求方法为POST,并把参数转换为二进制数据设置为请求体
    
    //1.创建会话对象
    NSURLSession *session = [NSURLSession sharedSession];
    
    //2.根据会话对象创建task
    NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/login"];
    
    //3.创建可变的请求对象
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    
    //4.修改请求方法为POST
    request.HTTPMethod = @"POST";
    
    //5.设置请求体
    request.HTTPBody = [@"username=520it&pwd=520it&type=JSON" dataUsingEncoding:NSUTF8StringEncoding];
    
    //6.根据会话对象创建一个Task(发送请求)
    /*
     第一个参数:请求对象
     第二个参数:completionHandler回调(请求完成【成功|失败】的回调)
                data:响应体信息(期望的数据)
                response:响应头信息,主要是对服务器端的描述
                error:错误信息,如果请求失败,则error有值
     */
    NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        
        //8.解析数据
        NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
        NSLog(@"%@",dict);
        
    }];
    
    //7.执行任务
    [dataTask resume];
}

6.4 NSURLSessionDataDelegate

#这里的代理方法只是简单的阐述下,具体的可以看参考文档

如果项目需要在网络请求数据的过程中,要做进一步的处理的话,需要调用NSURLSession的代理方法。

通常,使用代理方法需要先设置代理对象,但是通过查看NSURLSessionDataDelegate文档,我们可以看到如下,代理属性delegate为只读状态。

@property (nullable, readonly, retain) id  delegate;
// 1.delegateQueue参数表示协议方法将会在(NSOperationQueue)队列里面执行。(session的delegate属性是只读的,所以使用如下方法设置代理。)
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[[NSOperationQueue alloc] init]];
// 2.创建任务(因为要使用代理方法,就不需要block方式的初始化了)
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"http://172.16.2.254/php/phonelogin?yourname=%@&yourpass=%@&btn=login",yourname,yourpass]];
NSURLSessionDataTask *task = [session dataTaskWithRequest:[NSURLRequest requestWithURL:url]];
// 3.执行任务
[task resume];

关于代理行为:

#pragma mark -- NSURLSessionDataDelegate// 1.接收到服务器的响应
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler {
//【注意:此处需要允许处理服务器的响应,才会继续加载服务器的数据。 若在接收响应时需要对返回的参数进行处理(如获取响应头信息等),那么这些处理应该放在这个允许操作的前面。】
completionHandler(NSURLSessionResponseAllow);
}
// 2.接收到服务器的数据(此方法在接收数据过程会多次调用)
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data {
    // 处理每次接收的数据,例如每次拼接到自己创建的数据receiveData
    [self.receiveData appendData:data];
}
// 3.3.任务完成时调用(如果成功,error == nil)
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
    if(error == nil){
        /*
          请求完成,成功或者失败的处理
        */
    }
    else{
        NSLog(@"请求失败:%@",error);
    }
}

你可能感兴趣的:(iOS-网络请求的简介(NSURLConnection/NSURLSession))