2. NSURLConnection

NSURLConnection

一. iOS中发送HTTP请求的方案

  1. 苹果原生

    • NSURLConnection: 用法简单, 比较古老但是最直接的方案
    • NSURLSession: 功能比NSURLConnection强大, 苹果目前推荐使用的技术(2013年推出, iOS7开始的技术)
    • CFNetwork: NSURL类型框架的底层实现, 纯C语言
  2. 第三方框架

    • ASIHttpRequest: 外号HTTP终结者, 功能及其强大, 但是已经停止更新
    • AFNetworking: 简单易用, 提供了大部分常用的功能, 维护使用者多
    • MKNetworkKit: 简单易用, 印度阿三的产物, 使用者维护者较少
  3. 建议

    • 随着AFN框架的普遍性以及众多开发者合力维护, 建议尽量使用AFN框架
    • 并且, 为了提高开发效率, 建议直接使用三方框架

二. NSURLConnection发送GET请求

  1. 常用类的介绍

    • iOS中与网络相关的类, 都是以NSURL开头的类
    • NSURLRequest: 请求类, 每一个Request对象就代表一个请求, 其中包含的信息大致有:
      • NSURL对象, 代表请求的URL地址
      • 请求方法, 请求头, 请求体
      • 请求超时的信息(通过代理方法来监听)
      • 是否允许蜂窝移动网络发送请求等等....
    • NSMutableURLRequest: 他是NSURLRequest的子类, 可以在请求的同时包含更多的详细属性参数, 多用于POST请求
    • NSURLConnection: 负责处理网络交互的类
      • 负责发送请求, 建立客户端和服务器连接的类
      • 发送数据给服务器, 并收集来自服务器的响应数据
  2. NSURLConnection的使用步骤

    • 创建一个NSURL对象, 也就是设置请求路径
    • 使用NSURL对象来创建一个NSURLRequest对象, 并且设置请求头, 请求体
    • 使用NSURLConnection发送请求(发送请求的常见方式如下)
      • 同步请求: + (NSData *)sendSynchronousRequest:(NSURLRequest *)request returningResponse:(NSURLResponse **)response error:(NSError **)error
      • 异步请求(不会卡住主线程): 根据对服务器返回数据的处理方式不同, 可分为两种
        • block回调: + (void)sendAsynchronousRequest:(NSURLRequest*) request queue:(NSOperationQueue*) queue completionHandler:(void (^)(NSURLResponse* response, NSData* data, NSError* connectionError)) handler
        • 代理监听请求结果: 注意遵守协议
          • 首先, 要在发送请求的同时设置代理: + (NSURLConnection*)connectionWithRequest:(NSURLRequest *)request delegate:(id)delegate
          • 之后, 如果使用的是代理方法, 那么就需要手动发出网络请求- (void)start
          • 最后, 可以通过各种代理方法来处理返回的数据
  3. GET请求的代码示例:

     // 同步请求
     - (void)sendSync {
         
         // 1. 请求路径
         NSURL *url = [NSURL URLWithString:@"http://192.168.1.101:88/login?username=MyiOS&pwd=999&type=JSON"];
         
         // 2. 创建请求对象
         // requeset内部会自动提供默认的请求头信息,默认是以GET方式发送的
         NSURLRequest *request = [NSURLRequest requestWithURL:url];
         
         // 3. 发送请求
         // 3.1 响应头,他和响应体都是以data数据返回的
         NSURLResponse *response = nil;
         
         // 3.2 发送请求获取数据
         NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil];
         
         NSLog(@"%@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
         
         // 4. 打印响应头
         NSLog(@"%@", response);
         
         NSLog(@"%@", [NSThread currentThread]); // 在主线程解析数据
     }
     
     // 异步请求 - block回调
     - (void)sendAsync {
         
         // 1. 请求路径
         NSURL *url = [NSURL URLWithString:@"http://192.168.1.101:88/login?username=MyiOS&pwd=999&type=JSON"];
         
         // 2. 创建请求对象
         NSURLRequest *request = [NSURLRequest requestWithURL:url];
         
         // 3. 发送异步请求
         /*
          (NSURLRequest *)request  请求对象
          (NSOperationQueue *)queue  队列(决定代码在哪个线程中执行)
          completionHandler:(void (^)(NSURLResponse *response, NSData *data, NSError *connectionError))handler 连接完成后回调
             NSURLResponse *response  响应头信息
             NSData *data             返回的数据
             NSError *connectionError 如果请求失败,保存失败信息
          */
         [NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
             
             // 3.1 如果连接错误为nil,证明连接成功
             if (connectionError == nil) {
                 // 4. 解析返回的数据
                 NSLog(@"%@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
                 NSLog(@"%@", response);
                 NSLog(@"%@", [NSThread currentThread]); // 在子线程中解析数据
             }
         }];
         NSLog(@"%@", [NSThread currentThread]);
     }
     
     // 异步请求2 - 代理监听
     - (void)sendAsync2 {
         
         // 1. 创建请求路径
         NSURL *url = [NSURL URLWithString:@"http://192.168.1.101:88/login?username=MyiOS&pwd=999&type=JSON"];
         
         // 2. 创建请求对象
         NSURLRequest *request = [NSURLRequest requestWithURL:url];
         
         // 3. 设置代理,发送请求
         NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
         
         // 4. 开始发送网络请求
         [connection start];
     }
     
     #pragma mark - 代理方法,当发送了请求之后,会调用的方法
     // 1. 当接收到了响应的时候调用
     - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
         
         // 当接收到了响应,就创建data对象,准备接收数据
         self.data = [NSMutableData data];
         NSLog(@"%@", response);
     }
     
     // 2. 当接收到了数据的时候调用
     /*
      1> 该方法可能调用多次,当返回数据较大的时候,系统会一点一点接收数据
      2> 把每次接收的数据拼接起来,等接收完成,就是完整的数据了
      */
     - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
         
         // 查看当前数据的长度
         NSLog(@"%ld", data.length);
         
         // 拼接数据
         [self.data appendData:data];
     }
     
     // 3. 当请求失败的时候调用该方法
     - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
         
         NSLog(@"请求失败");
     }
     
     // 4. 当请求完成的时候调用,请求已经完成,接收数据完毕
     - (void)connectionDidFinishLoading:(NSURLConnection *)connection {
         
         // 解析数据
         NSLog(@"%@", [[NSString alloc] initWithData:self.data encoding:NSUTF8StringEncoding]);
         
         NSLog(@"数据接收完毕");
         NSLog(@"%@", [NSThread currentThread]);
     }
    

三. NSURLConnection发送POST请求

  1. NSMutableURLRequest

    • 普通的NSURLRequest默认发送的是GET请求, GET只能发送一些简单的请求, 用于获取数据
    • 而NSMutableURLRequest, 可以包含更多的请求信息, 如:
      • 修改请求方法: 默认的请求方式为GET
      • 设置最大请求时间: 当超过最大时间还没连接成功的话, 那么认为请求失败
      • 设置请求头信息: 比如设置客户端的信息(当前设备为iOS9.0)
      • 设置请求体: 请求体是将NSData的二进制数据, 发送给服务器, 通过这点就可以发送文件
    • 补充GET和POST的请求格式
      • GET: http://192.168.2.101:40/login?username=MyiOS&pwd=999&type=JSON
      • POST: http://192.168.2.101:40/lgoin
      • 从上可以看出, GET在?之后, 将参数一同发送给了服务器
      • 而POST则是将参数单独抽取出来, 放在Request对象中发送
  2. POST请求的简单实现代码

     - (void)post {
         
         // 1. 确定请求路径
         NSURL *url = [NSURL URLWithString:@"http://192.168.2.101:40/lgoin"];
         
         // 2. 创建可变请求对象
         NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
         
         // 3. 修改请求方法为POST(因为默认为GET)
         request.HTTPMethod = @"POST";
         
         // 4. 设置最大请求时间
         request.timeoutInterval = 15; // 如果请求时间超过15秒还没得到响应,那么认为请求失败
         
         // 5. 设置请求头信息(Key为User-Agent)
         [request setValue:@"iOS 9.0" forHTTPHeaderField:@"User-Agent"];
         
         // 6. 设置请求体(将参数发送给服务器)
         request.HTTPBody = [@"username=520it&pwd=520it&type=JSON" dataUsingEncoding:NSUTF8StringEncoding];
         
         // 7. 发送请求(异步)
         [NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
             
             // 接收数据并解析
             if (connectionError == nil) {
                 
                 NSLog(@"数据接收完毕,开始解析");
                 NSLog(@"%@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
             }
         }];
     }
    
  3. 补充:

    • 如果你的系统版本是适配iOS7.0以后的版本, 尽量使用NSURLSession
    • 同时, 在企业开发中, 尽量使用AFN等三方框架来处理你的网络请求, 提高开发效率

你可能感兴趣的:(2. NSURLConnection)