iOS学习笔记21-NSUrlSession与NSUrlConnection

首先 介绍一下HTTP协议

URL的全称是Uniform Resource Locator(统一资源定位符) 

 

URL中常见的协议有

HTTP超文本传输协议,访问的是远程的网络资源

FILE 访问的是本地计算机的资源

MAILTO 访问的是电子邮件地址

FTP 访问的是共享主机的文件资源

HTTP协议的作用是

1,规定了客户端和服务端之间的数据传输格式

2,让客户端和服务器能有效的进行数据沟通

为什么选择HTTP

1,简单快速

2,灵活

3,节省传输时间

HTTP的通信过程

1,请求:客户端向服务器索要数据

2,响应:服务器返回客户端相应的数据 

HTTP具体通信过程

1,请求

HTTP协议规定:1个完整的客户端发给服务器的HTTP请求包含以下内容

      1)请求行:包含了请求方法,请求资源路径,HTTP协议版本

        GET /MJServer/resources/images/1.jpg HTTP/1.1

      2)请求头:包含了对客户端的环境描述,客户端请求的主机地址等信息

        Host: 192.168.1.105:8080 // 客户端想访问的服务器主机地址

        User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9) Firefox/30.0// 客户端的类型,客户端的软件环境

         Accept: text/html, */*// 客户端所能接收的数据类型

        Accept-Language: zh-cn // 客户端的语言环境

       Accept-Encoding: gzip // 客户端支持的数据压缩格式

        3)请求体:客户端发给服务器的具体数据,比如文件数据

2,响应

 客户端向服务器发送请求,服务器应当做出响应,即返回数据给客户端

HTTP协议规定:1个完整的HTTP响应包含以下内容:

1)状态行:包含了HTTP协议版本,状态码,状态英文名称

HTTP/1.1 200 OK

2)响应头: 包含了对服务器的描述,对返回数据的描述

Server: Apache-Coyote/1.1 // 服务器的类型

Content-Type: image/jpeg // 返回数据的类型

Content-Length: 56811 // 返回数据的长度

                  Date: Mon, 23 Jun 2014 12:54:52 GMT // 响应的时间

3)实体内容:服务器返回给客户端的具体数据,比如文件数据

 

发送HTTP请求的方法

八种请求方法:GET、POST、OPTIONS、HEAD、PUT、DELETE、TRACE、CONNECT、PATCH

不同方法对资源的不同操作方式

            PUT :增

DELETE :删

POST:改

GET:查

提示:最常用的是GET和POST(实际上GET和POST都能办到增删改查)

GET POST请求

参数就是传递给服务器的具体数据,比如登录时的帐号、密码

GET和POST对比:GET和POST的主要区别表现在数据传递上

GET

在请求URL后面以?的形式跟上发给服务器的参数,多个参数之间用&隔开,比如http://ww.test.com/login?username=123&pwd=234&type=JSON

注意:由于浏览器和服务器对URL长度有限制,因此在URL后面附带的参数是有限制的,通常不能超过1KB

POST

发给服务器的参数全部放在请求体中

理论上,POST传递的数据量没有限制(具体还得看服务器的处理能力)

选择GET和POST的建议

(1)如果要传递大量数据,比如文件上传,只能用POST请求

(2)GET的安全性比POST要差些,如果包含机密敏感信息,建议用POST

(3)如果仅仅是索取数据(数据查询),建议使用GET

(4)如果是增加、修改、删除数据,建议使用POST  

iOS中发送HTTP请求的方案

1,苹果原生

NSURLConnection:用法简单,最古老最经典最直接的一种方案

NSURLSession:iOS 7新出的技术,功能比NSURLConnection更加强大

CFNetwork:NSURL*的底层,纯C语言

2,第三方

ASIHttpRequest:外号“HTTP终结者”,功能极其强大,可惜早已停止更新

AFNetworking:简单易用,提供了基本够用的常用功能

二,GET POST

创建GET请求 

     NSString *str = @"";

    NSURL *url = [NSURL URLWithString:str];

    

    NSURLRequest *request = [NSURLRequest requestWithURL:url];

创建POST请求


    NSString *str = @"";

    NSURL *url = [NSURL URLWithString:str];

    

    NSURLRequest *request = [NSURLRequest requestWithURL:url];

    request.HTTPMethod = @"POST";

    request.timeoutInterval = 5.0;

    request.HTTPBody = @""; 

如果出现中文,需要进行转码

NSString *strURL = @"";

    strURL = [strURL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

    NSURL *url = [NSURL URLWithString:strURL];

     

    

三,NSURLConnection 使用

 常用类

1 )NSURL 请求地址

2)NSURLREQUEST 封装一个请求,保存发给服务器的全部数据,包括一个NSURL对象

3)NSMutableURLRequest

4)NSURLCONNECTION 负责发送请求,建立客户端和服务端的链接,发送NSURLREQUEST的数据给服务端,并收集响应数据

发送同步请求代码


    //1设置请求路径

    NSString *str = @"";

    NSURL *url = [NSURL URLWithString:str];

    //2创建请求对象

    NSURLRequest *request = [NSURLRequest requestWithURL:url];

    

    //发送请求

    //发送同步请求,在主线程执行

    NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil]; //(一直在等待服务器返回数据,这行代码会卡住,如果服务器没有返回数据,那么在主线程UI会卡住不能继续执行操作) 

发送异步请求
发送异步请求有两种方式:
1)使用block回调

            2)代理 

 NSString *str = @"";

    NSURL *url = [NSURL URLWithString:str];

    NSURLRequest *request = [NSURLRequest requestWithURL:url];

    

    //创建一个队列,获取一个朱队列

    NSOperationQueue *queue = [NSOperationQueue mainQueue];

    [NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {

        NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];

    }];


使用代理方法发送异步请求

//当接收到服务器的响应(连通了服务器)时会调用


-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response


//当接收到服务器的数据时会调用(可能会被调用多次,每次只传递部分数据)


-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data


//当服务器的数据加载完毕时就会调用


-(void)connectionDidFinishLoading:(NSURLConnection *)connection


//请求错误(失败)的时候调用(请求超时断网没有网,一般指客户端错误)


-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error

使用代理方法GET数据实例


- (void)viewDidLoad {

    [super viewDidLoad];


    NSString *str = @"";

    NSURL *url = [NSURL URLWithString:str];

    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];

    request.timeoutInterval = 5.0;

    NSURLConnection *con = [NSURLConnection connectionWithRequest:request delegate:self];

    [con start]; 


 *当接收到服务器的响应(连通了服务器)时会调用

 */

-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response

{

    NSLog(@"接收到服务器的响应");

    //初始化数据

    self.responseData=[NSMutableData data];

}


*当接收到服务器的数据时会调用(可能会被调用多次,每次只传递部分数据)

*/

-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data

{

    NSLog(@"接收到服务器的数据");

    //拼接数据

    [self.responseData appendData:data];

        NSLog(@"%d---%@--",self.responseData.length,[NSThread currentThread]);

}

-(void)connectionDidFinishLoading:(NSURLConnection *)connection

 //处理服务器返回的所有数据

    NSDictionary *dict=[NSJSONSerialization JSONObjectWithData:self.responseData options:NSJSONReadingMutableLeaves error:nil];

    

    //判断后,在界面提示登录信息

    NSString *error=dict[@"error"];

    if (error) {

        [MBProgressHUD showError:error];

    }else

    {

        NSString *success=dict[@"success"];

        [MBProgressHUD showSuccess:success];

    }

    NSLog(@"%d---%@--",self.responseData.length,[NSThread currentThread]);

}


 *请求错误(失败)的时候调用(请求超时断网没有网,一般指客户端错误)

 */

-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error

{

//     NSLog(@"请求错误");

    //隐藏HUD

    [MBProgressHUD hideHUD];

    [MBProgressHUD showError:@"网络繁忙,请稍后重试!"];

}

@end

NSMutableURLRequest

NSMutableURLRequest是NSURLRequest的子类,常用方法有

设置请求超时等待时间(超过这个时间就算超时,请求失败)- (void)setTimeoutInterval:(NSTimeInterval)seconds;

设置请求方法(比如GET和POST)- (void)setHTTPMethod:(NSString *)method;

设置请求体- (void)setHTTPBody:(NSData *)data;

设置请求头- (void)setValue:(NSString *)value forHTTPHeaderField:(NSString *)field; 

原文地址:https://www.cnblogs.com/adodo/p/5218824.html