美文网首页
2. NSURLConnection

2. NSURLConnection

作者: 面糊 | 来源:发表于2016-07-04 15:24 被阅读55次

    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的请求格式
    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

          本文链接:https://www.haomeiwen.com/subject/hjocjttx.html