文章目录
前言
- 最近写项目开始和后台对接了,测试接口需要用到网络请求相关知识,才能和后台进行交互。
- 暂时学习了使用
NSURLSession
(现在流行的苹果网络框架)进行网络请求
NSURLSession
NSURLSession
,苹果对它的定位是作为NSURLConnection
的替代者NSURLSession
的使用相对于之前的NSURLConnection
更简单,而且不用处理Runloop相关的东西。NSURLSession
只提供了异步请求方式而没有提供同步请求方式
NSURLSession替换NSURLConnection
- 在iOS9.0之后,以前使用的
NSURLConnection
过期,苹果推荐使用NSURLSession
来替换NSURLConnection
完成网路请求相关操作。 NSURLSession
的优势:
-
NSURLSession
支持http2.0协议
-
- 处理下载任务的时候可以直接把数据下载到磁盘中
-
- 支持后台下载和上传
-
- 同一个
session
发送多次请求,只需要建立一次连接(复用了TCP)
- 同一个
-
- 提供了全局的
session
并且可以统一配置,使用更加方便
- 提供了全局的
-
- 下载的时候是多线程异步处理,效率更高
NSURLSession
的使用非常简单,先根据会话对象创建一个请求Task
,然后执行该Task
即可NSURLSessionTask
及其子类
-
NSURLSessionTask
本身是一个抽象类,在使用的时候,通常是根据具体的需求使用它的几个子类
-
NSURLSessionDataTask
可以用来发送常见的Get,Post请求,既可以用来上传也可以用来下载
-
NSURLSessionDownloadTask
可以用来发送下载请求,专门用来下载数据
-
NSURLSessionUploadTask
可以用来发送上传请求,专门用来上传数据
父类NSURLSessionTask中,部分常用方法:
resume
:开始或继续请求,创建后的task
默认是挂起的,需要手动调用resume
才可以开始请求。suspend
:挂起当前请求。主要是下载请求用的多一些,普通请求挂起后都会重新开始请求。下载请求挂起后,只要不超过NSURLRequest
设置的timeout
时间,调用resume
就是继续请求。cancel
:取消当前请求。任务会被标记为取消,并在未来某个时间调用URLSession:task:didCompleteWithError:
方法。
Get请求
- get请求其实就是通过URL来传递数据
- 一个标准的URL网址,在最后有一个
querystring
部分,表示对页面查询,用?来表示这部分,内容必须是k=v
,对个参数用&
来链接,此时页面将能收到这些参数
流程
- 确定请求路径(一般由公司的后台开发人员以接口文档的方式提供),Get请求参数直接跟在URL后面
- 创建请求对象(默认包含了请求头和请求方法【Get】),此步骤可以省略
- 创建会话对象(
NSURLSession
) - 根据会话对象创建请求任务(
NSURLSessionDataTask
) - 当得到服务器返回的响应后,解析数据
(XML|JSON|HTTP)
- 执行Task
1. 确定请求路径
//1. 确定请求路径
NSURL *url = [NSURL URLWithString:@"http://47.94.56.32:8085/users/login"];
2. 创建请求对象
NSURLRequest *request = [NSURLRequest requestWithURL:url];
请求对象内部默认已经包含了请求头和请求方法(GET)
3. 获得会话对象
NSURLSession *session = [NSURLSession sharedSession];
4. 根据会话对象创建一个Task(发送请求)
Get请求有两种方式:
第一种:
NSURLSessionDataTask *task = [session dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
}];
第一个参数:请求路径
第二个参数:
completionHandler
回调(请求完成【成功|失败】的回调)data
:响应体信息(期望的数据)response
:响应头信息,主要是对服务器端的描述error
:错误信息,如果请求失败,则error
有值
注意:
- 该方法内部会自动将请求路径包装成一个请求对象,该请求对象默认包含了请求头信息和请求方法(GET)
- 如果要发送的是POST请求,则不能使用该方法
第二种:
NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
}];
第一个参数:请求对象
第二个参数:
completionHandler
回调(请求完成【成功|失败】的回调)data
:响应体信息(期望的数据)response
:响应头信息,主要是对服务器端的描述error
:错误信息,如果请求失败,则error
有值
5. 解析服务器返回的数据
此处返回的数据是JSON格式的,因此使用NSJSONSerialization进行反序列化处理
//说明(此处返回的数据是JSON格式的,因此使用NSJSONSerialization进行反序列化处理)
NSLog(@"Get请求返回的响应信息:%@",[NSJSONSerialization
JSONObjectWithData:data options:kNilOptions error:nil]);
6. 执行任务
[task resume];
Post请求
流程
- 确定请求路径(一般由公司的后台开发人员以接口文档的方式提供)
- 创建可变的请求对象(因为需要修改),此步骤不可以省略
- 修改请求方法为
POST
- 设置请求体,把参数转换为二进制数据并设置请求体
- 创建会话对象(
NSURLSession
) - 根据会话对象创建请求任务(
NSURLSessionDataTask
) - 当得到服务器返回的响应后,解析数据
(XML|JSON|HTTP)
- 执行Task
具体代码步骤与上述get请求相同,除了第三第四步在Get请求中是没有的,接下来将单独讲第三第四步
修改请求方法为POST
request.HTTPMethod = @"POST";
设置请求体
这是利用POST方法与后台进行数据请求的关键一步
request.HTTPBody = [@"name=jack&password=123"
dataUsingEncoding:NSUTF8StringEncoding];
也可以利用NSData
进行Json解析再放在请求体中
NSMutableDictionary *parameters = [NSMutableDictionary dictionary];
parameters[@"username"] = _usernameString;
parameters[@"password"] = _passwordString;
NSData *data = [NSJSONSerialization dataWithJSONObject:parameters options:NSJSONWritingPrettyPrinted error:nil];
request.HTTPBody = data;
Get与Post请求比较
区别:
- GET向服务器获取数据,POST向服务器发送请求
- GET会把查询字符串的参数追加到URL的末尾,POST请求则把数据作为请求的主体来提交,可以包含非常多的数据,因此客户可以看到GET提交的参数,POST则不可以。
- GET请求提交的数据直接加到URL的末尾,所以大小有限制,而POST则没有
- POST安全性比GET高
- 对于get方式,服务器端有
Request.QueryString
来获取变量的值,对于post方式,服务器用Request.Form
来获取提交的数据 - get形式的URL对搜索引擎更加友好,可以提高搜索引擎排名。而POST甚至会阻止爬虫和搜索引擎的访问
info.plist文件配置
要对info.plist
文件进行配置之后才能正常进行网络请求
遇到的问题
不同的任务 是不是不能使用 [NSURLSession sharedSession]? 这个不是单例吗?
NSURLSession
本身就是线程安全的,所有task
都是异步的。因此不同任务可以都使用[NSURLSession sharedSession]
, 而且没有定制化需求的话,建议都使用。共用一个session
的话,会有优化。