zoukankan      html  css  js  c++  java
  • 网络处理1-异步GET请求

    前言

    云计算

    近几年来,云计算是一个非常热门的技术名词,很多专家认为,云计算会改变互联网的技术基础,甚至会影响整个产业的格局。可能还很多人不了解什么是云计算,简单来说,就是把用户的数据(比如文档、照片等)、用户需要使用的软件、用户需要搜索的资源都保存在"云端",并不用保存在用户本地。你可以将"云端"看做了一台超级计算机,其实是由无数台大型服务器组成的。

    移动应用

    现在很多的移动应用也类似于"云计算"的模式,比如新浪微博,用户的数据都是保存在新浪服务器的数据库里面。当用户想在手机上看到自己的微博数据时,大致需要以下几个过程:

    1.新浪微博手机客户端发送HTTP请求到新浪服务器

    2.服务器响应后返回数据给客户端

    3.客户端对数据进行解析后以图形界面的形式(如列表形式)呈现给用户

    网络处理这一块在移动开发中占据着非常重要的地位,我们这个专题主要来学习iOS网络处理中的HTTP请求。

    一、API简介

    如果你想在iOS中发送Http请求的话,有很多方式可以选择,我在这里介绍几个常见的:

    1.苹果自带的API

    1> Core Foundation框架中的CFNetwork API:纯C语言的API,性能非常高

    2> Foundation框架中的NSURLConnection API:Objective-C的API,性能也不错,简单易用

    2.第3方开源框架

    1> ASIHttpRequest

    2> AFNetworking

    我们这个专题主要来研究NSURLConnection的使用,至于第3方框架的学习,网上也有很多资源可以搜索。

    二、发送异步的GET请求

    众所周知,HTTP的主要请求方式有2种:GET请求和POST请求,接下来先演示下如何发送一个GET请求。

    需要注意的是,你最好发送一个异步请求,不要发送同步请求。iOS程序启动后,系统会默认创建一条主线程,也称为UI线程,这条主线程专门用来渲染UI界面、处理UI界面和用户之间的交互,比如处理用户的触摸事件、文本输入事件等。所谓异步请求,就是在后台线程发送请求,不在主线程发送请求。一般情况下,客户端发出请求后,需要等待服务器的数据返回,如果服务器处理速度比较慢或者网速慢的话,可能要等很长时间。因此,如果你执意要发送同步请求,也就是在主线程发送请求,会造成主线程阻塞,容易出现卡机现象,给用户带来极差的体验。

    1.利用NSURLConnection发送异步请求

    复制代码
     1 // 请求地址
     2 NSString *urlString = @"http://192.168.1.102:8080/MJServer/login?username=123&pwd=123";
     3 
     4 // 初始化一个NSURL对象
     5 NSURL *url = [NSURL URLWithString:urlString];
     6 
     7 // 初始化一个请求
     8 NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
     9 // 设置请求方法,可以省略,默认就是GET请求
    10 request.HTTPMethod = @"GET";
    11 // 如果60秒过后服务器还没有相应,就算请求超时
    12 request.timeoutInterval = 60;
    13 
    14 // 初始化一个连接
    15 NSURLConnection *conn = [NSURLConnection connectionWithRequest:request delegate:self];
    16 // 开始一个异步请求
    17 [conn start];
    复制代码

    1> 第2行的是请求地址,由于是GET请求,请求参数是直接拼接到路径后面的

    2> 第17行调用NSURLConnection的start方法发送一个HTPP请求,默认就是异步请求

    2.NSURLConnectionDataDelegate

    在前面的第15行代码中,初始化NSURLConnection对象的时候传了个self做代理(delegate),我这里的self是控制器。在客户端跟服务器交互过程会不断地给这个代理对象发送消息,也就是会不断地调用代理对象的相应方法。iOS在NSURLConnectionDataDelegate协议中定义了很多代理方法,我这里只介绍常用的3个方法:

    复制代码
     1 #pragma mark - NSURLConnectionDataDelegate
     2 #pragma mark 接收到服务器返回的数据时调用(如果数据比较多,这个方法可能会被调用多次)
     3 - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
     4     NSLog(@"接收到服务器返回的数据");
     5     // 拼接数据
     6     [self.data appendData:data];
     7 }
     8 
     9 #pragma mark 网络连接出错时调用
    10 - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
    11     NSLog(@"网络连接出错:%@", [error localizedDescription]);
    12 }
    13 
    14 #pragma mark 服务器的数据已经接收完毕时调用
    15 - (void)connectionDidFinishLoading:(NSURLConnection *)connection {
    16     NSLog(@"服务器的数据已经接收完毕");
    17     // 解析成字符串数据
    18     NSString *str = [[[NSString alloc] initWithData:self.data encoding:NSUTF8StringEncoding] autorelease];
    19     NSLog(@"%@", str);
    20 }
    复制代码

    1> 当服务器有数据返回时就会调用第3行的代理方法,返回的数据以NSData的格式传入。如果数据比较多,比如下载大文件时,这个方法可能会被调用多次。

    2> 第6行用一个NSMutableData对象拼接服务器返回的所有数据,self.data是一个NSMutableData。

    3> 当服务器已经成功返回所有的数据后,会调用第15行的代理方法,到此为止,self.data里面存放着服务器端返回的所有数据

    4> 由于我这边服务器返回的是JSON字符串数据,所以在18行将self.data转换为NSString,然后打印出来看看数据对不对

    3.对中文参数进行编码

    如果你的请求参数中含有中文,必须先进行编码,然后再拼接到请求路径后面。

    下面的请求路径写法是错误的:

    1 NSString *urlString = @"http://192.168.1.102:8080/MJServer/login?username=母鸡";

    应该这样写:

    复制代码
    1 // 使用UTF-8对中文参数进行编码
    2 NSString *param = [@"母鸡" stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    3 
    4 // 请求地址
    5 NSString *baseUrl = @"http://192.168.1.102:8080/MJServer/login?username=";
    6 NSString *urlString = [baseUrl stringByAppendingString:param];
    复制代码

    1> 第2行使用UTF-8对中文参数进行编码

    2> 在第6行拼接编码后的参数到请求路径中

    4.取消请求

    如果用户的网络状况不是很好,那么在登录的过程中,用户很可能会点击"取消"按钮来取消登录

    当用户点击了取消按钮,我们也应该终止之前发送的请求,这时候可以这样做

    [conn cancel];

    conn是一个NSURLConnection对象

     
  • 相关阅读:
    【Leetcode】23. Merge k Sorted Lists
    【Leetcode】109. Convert Sorted List to Binary Search Tree
    【Leetcode】142.Linked List Cycle II
    【Leetcode】143. Reorder List
    【Leetcode】147. Insertion Sort List
    【Leetcode】86. Partition List
    jenkins 配置安全邮件
    python 发送安全邮件
    phpstorm 同步远程服务器代码
    phpUnit 断言
  • 原文地址:https://www.cnblogs.com/pb89/p/4708806.html
Copyright © 2011-2022 走看看