iOS--网络请求的基础知识

作者: Aaron_ZhangKH | 来源:发表于2016-10-09 09:41 被阅读0次

    前言

    在iOS的入门阶段,相信大家都会经过一个网络阶段,在这个阶段,我们要学习网路的基础知识,特别是关于如何和服务器进行数据交流这一块。而作为菜鸟级的coder,最先我们都是要学习如何从服务器“要”数据,这也称为网络请求。本文主要是针对网络请求的基础知识进行描述,包括网络协议、网络请求的分类、常用请求方法、NSURLConnection的使用和一些常规的注意事项等。

    最常见的两种网络协议

    • Http(HyperText Transfer Protocol)
      • 又称为超文本传输协议,是互联网上应用最为广泛的一种网络协议。
      • Http是一个客户端和服务器端请求和应答的标准(TCP)。客户端是终端用户,服务器端是网站。通过使用Web浏览器、网络爬虫或者其它的工具,客户端发起一个到服务器上指定端口(默认端口为80)的HTTP请求来获得数据。
    • HttpS
      • 可以理解为加密后的http协议,现在苹果正在大力限制开发者使用http协议,而强制要求使用https协议,不过因为https的使用需要每年支付一定的费用,所以目前大多数中国的互联网公司还以使用http为主。
    • 为什么选择http协议
      • 简单快速
        • 因为Http协议简单,所以HTTP服务器的程序规模小,因而通信速度很快
      • 灵活
        • HTTP允许传输各种各样的数据
    • HTTP的基本通信过程(两大步骤)
      • 请求:客户端向服务器索要数据
      • 响应:服务器返回客户端相应的数据
      • 具体通信过程可以参考下图


        http基本通信过程

    Http最常用的请求方法

    • GET请求
      • 从指定的服务器中获取数据
      • 特点:
        • GET请求能够被缓存
        • GET请求会保存在浏览器的浏览记录中
        • 以GET请求的URL能够保存为浏览器书签
        • GET请求有长度限制
        • GET请求不安全
    • POST请求
      • 提交数据给指定的服务器处理
      • 特点
        • POST请求不能被缓存下来
        • POST请求不会保存在浏览器浏览记录中
        • 以POST请求的URL无法保存为浏览器书签
        • POST请求没有长度限制
        • 相对于GET请求来说, POST请求更加安全

    Http网络请求的结构

    • 请求头
      • 客户端发出的网络请求的“头”部分
      • 请求头一般包含一些简单的配置信息,例如客户端信息,是GET请求还是POST请求等等。
    • 请求体
      • 客户端发出的网络请求的“身体”部分
      • 具体要请求的内容的正文,以及一些提交给服务器的保密内容,例如用户名和密码
    • 响应头
      • 服务器返回的数据的配置信息,例如数据类型,响应结果,响应码等零碎的信息
      • 在代码中一般表达为response这个变量
    • 响应体
      • 服务器返回的数据的具体内容(一般由服务器分段返回)
      • 在代码中一般表达为data这个变量

    网络请求的方式分类(重点)

       **同步请求**(一旦发出同步请求,如果服务器不响应,就算你等到天荒地老客户端也不会继续执行后续操作,一般开发中不建议使用)
       具体的请求代码如下所示:
    
     先创建URL对象
     NSURL *url = [NSURL URLWithString:@"http://dl_dir.qq.com/qqfile/qq/QQforMac/QQ_V2.4.1.dmg"];
    
    /*
     第1种方法
     */
    NSString *string = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:nil];
    
    /*
     第2种方法
     */
    NSData *data = [NSData dataWithContentsOfURL:url];
    
    /*
     第3种方法(使用NSURLConnection发送同步请求)
     */
    3.1 创建请求对象
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    3.2 发送同步请求
    [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
    
       异步请求(一旦请求发出,不用等服务器有响应就能继续后续操作,开发中最常用的请求)
       具体的请求代码如下所示:
    
    /*
     第1种方法
     */
    1.1 创建URL对象
    NSURL *url = [NSURL URLWithString:@"http://dl_dir.qq.com/qqfile/qq/QQforMac/QQ_V2.4.1.dmg"];
    
    1.2 创建请求对象
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    
    1.3 发送异步请求
    [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
        NSLog(@"请求完成");
    }];
    
    /*
        第2种方法 (使用NSURLConnection的代理方法)
        步骤:发送网络请求 + 实现四个代理方法
    */
         2.1 创建请求对象
        NSURLRequest *request = [NSURLRequest requestWithURL:url];
        
         2.2 发送异步请求, 并绑定其代理为self
     [NSURLConnection connectionWithRequest:request delegate:self];
     
         2.3 实现第一个代理方法(只有在收到服务器响应时会触发)
         //注意:参数response即服务器返回的响应头, 包含返回数据的各种信息, 如文件名,文件大小,文件类型
         - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
    {
        //1. 清空数据 
        (事先定义一个全局变量_downloadData来保存请求下来的数据)
        (在保存数据之前, 为了防止和上一次请求的数据发生混合, 应该先清除上一次的数据)
        self.downloadData.length = 0;
        
        //2. 获取文件总大小
        self.allSizeBytes = response.expectedContentLength;
        
        //3. 获取文件名字
        NSString *filename = response.suggestedFilename;
        NSLog(@"文件名字:%@",filename);
    
        
        //4. 获取文件类型
        NSString *type = response.MIMEType;
        NSLog(@"文件类型:%@",type);
        
        //5. 获取状态码
        NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
        NSInteger statusCode = httpResponse.statusCode;
        NSLog(@"状态码:%ld",statusCode);
    }
    
        2.4 实现第二个代理方法(接受服务器传过来的数据) 
    服务器会分段把数据传给客户端, 因此该方法可能会走多次.
     - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    //叠加数据
    [self.downloadData appendData:data];
     }
    
        2.5 实现第三个代理方法(下载完成了会触发)
        (void)connectionDidFinishLoading:(NSURLConnection *)connection
    {
        NSLog(@"下载完成");
        //将下载完成的数据复制给图片
        self.image = [UIImage imageWithData:self.downloadData];
    }
    
    2.6 实现第四个代理方法(下载失败时触发)
    -  (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
    {
        NSLog(@"下载失败--%@",error);
    }
    

    网络请求的注意事项

    • 中文编码问题
      • 在大天朝,我们难免会在URL中用到中文,这个时候如果不对其进行转码就用来进行网络请求,是请求不到数据的!请求不到数据的!请求不到数据的!(重要的事情说够三遍),因此一定要对包含中文的URLString先进行转码,具体代码如下所示:
     先对URLString进行UTF8编码 --> 再转换成URL
          
          NSString *urlString = @"https://api.douban.com/v2/book/search?q=开发" 
          urlString = [urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
          NSURL *url = [NSURL URLWithString:urlStr];
    

    结语

    本文讲述的仅仅只是针对刚入门的iOS菜鸟coder的基础知识,但也是作为一名合格的iOS前端攻城狮必学的知识,当然,在互联网时代,我们有了众大神的第三方框架,也很少会再去使用NSURLConnection这个过时的类,更何况苹果也已经推出了NSURLSession这个功能强大的类。有兴趣的朋友还可以在github下载一个大神写的第三方框架(AFNetworking)。

    相关文章

      网友评论

        本文标题:iOS--网络请求的基础知识

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