iOS网络相关类介绍
网络请求地址对象——NSURL
url 介绍
- url,统一资源定位符,也被称为网址,因特网上标准的资源网址
- 一个典型的url: http://lily:[email protected]/search? hl=en&source=hp&q=mysql&aq=f&oq=&aqi=g10#page
- url的符语法: 协议://授权/路径?查询
- 协议: ftp://(文件传输协议) http://(超⽂本传输协议) https://(安全超文本传输协议) file://(本地文件协议)
url作为网址字符串包含很多请求参数,NSURL对网址字符串进行封装, 可以使用NSURL对象获取相应的参数。
absoluteString
: http://lily:[email protected]/search? hl=en&source=hp&q=mysql&aq=f&oq=&aqi=g10#page
scheme
: http
host
: www.google.com
user
: lily
password
: 123456
port
: 8080
query
: hl=en&source=hp&q=mysql&aq=f&oq=&aqi=g10
网络请求对象 ——NSURLRequest,NSMultableRequest
可以使用URL加载一个请求,设置请求方法HTTPMethod
POST等,设置请求体HTTPBody
网络请求的参数,并且可以设置缓存策略,请求等待时间。
初始化方法:
- (instancetype)initWithURL:(NSURL *)URL;
- (instancetype)initWithURL:(NSURL *)URL cachePolicy:(NSURLRequestCachePolicy)cachePolicy timeoutInterval:(NSTimeInterval)timeoutInterval NS_DESIGNATED_INITIALIZER;
网络连接对象—— NSURLSession
NSURLConnection
iOS9之后 弃用,使用NSURLSession
代替。NSURLSession提供了NSURLRequest对象的网络机制的策略配置NSURLSessionConfiguration
。NSURLSession可以设置代理NSURLSessionDelegate
,代理方法会在网络请求的生命周期中调用, 参考文档。
NSURLSessionConfiguration
创建session会话时生成configuration对象的副本,会话创建后不能修改会话的configuration。
- 默认配置
defaultSessionConfiguration
:使用钥匙串,缓存,cookie存储。 - 短暂的会话
ephemeralSessionConfiguration
:不存储 - 后台会话
+ (NSURLSessionConfiguration *)backgroundSessionConfigurationWithIdentifier:(NSString *)identifier API_AVAILABLE(macos(10.10), ios(8.0), watchos(2.0), tvos(9.0));
:用于在某些约束条件下,代表已挂起的应用程序执行网络操作。
NSURLSessionConfiguration为NSURLSession配置一些请求所需要的策略。如:超时、缓存策略、链接需求的,在做有VPN登录的项目中也是在设置config的connectionProxyDictionary
属性。如果NSURLRequest中也做了一些指定。session也会遵循NSURLRequest的限定,但是如果configuration有更加严格的限定,仍以configuration为主。
NSURLSession的子类
NSURLSession是一个抽象类,会创建子类实现具体操作,获取数据和下载、上传文件的实际工作,调用resume
方法。就像名字的意思,NSURLSession创建一个会话,它的子类Task执行任务。
- NSURLSessionDataTask:不提供NSURLSessionTask的任何附加功能,它的存在仅仅是提供与下载和上传任务的词汇区分。
- NSURLSessionUploadTask:将文件从磁盘上传到服务器,通常通过HTTP POST或PUT方法。
- NSURLSessionDownloadTask:将文件从远程服务下载到临时文件位置。
- NSURLSessionStreamTask:读取写入TCPTCP/IP流接口, k可以用于执行异步读写, iOS9之后可用。
网络链接协议——NSURLSessionDelegate
tasks共享一个代理,代理响应各种事件,提供和获取信息,当身份验证失败时,当服务器的数据到达时,当数据准备缓存时等等,逐步地列出回话执行任务时发生的事件以及 调用哪个委托方法。
NSURLSessionDelegate 处理会话事件代理
-
- (void)URLSession:(NSURLSession *)session didBecomeInvalidWithError:(nullable NSError *)error;
会话接收的最后一个消息,返回错误信息 -
- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))completionHandler;
如果实现该方法,当链接身份验证时,代理将向底层连接提供身份验证凭证,如果未实现此代理方法,则使用默认处理。 -
- (void)URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session API_AVAILABLE(ios(7.0), watchos(2.0), tvos(9.0)) API_UNAVAILABLE(macos);
如果应用程序收到了-application: handleeventsforbackgrounddurlsession:completionHandler: message
,会话委托将接收到这条消息,以表明之前为这个会话排队的所有消息已经被发送。此时可以安全地调用先前存储的完成处理程序,或者开始任何将导致调用完成处理程序的内部更新。
NSURLSessionTaskDelegate 通用代理
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(nullable NSError *)error;
请求结束或者是失败的时候调用
NSURLSessionDataDelegate 数据任务
#pragma mark - NSURLSessionDataDelegate
// 使用block方式初始化task的话设置的代理方法将无效
/**
* 接收到服务器的响应 它默认会取消该请求
*
* @param session 会话对象
* @param dataTask 请求任务
* @param response 响应头信息
* @param completionHandler 回调 传给系统
*/
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(nonnull NSURLResponse *)response completionHandler:(nonnull void (^)(NSURLSessionResponseDisposition))completionHandler {
/*
NSURLSessionResponseCancel = 0,取消 默认
NSURLSessionResponseAllow = 1, 接收
NSURLSessionResponseBecomeDownload = 2, 变成下载任务
NSURLSessionResponseBecomeStream 变成流
*/
completionHandler(NSURLSessionResponseAllow);
}
//接收到服务器的响应 调用多次
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data {
}
NSURLSessionDownloadDelegate下载
#pragma mark - NSURLSessionDownloadDelegate
- (void)URLSession:(NSURLSession *)session downloadTask:(nonnull NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite {
}
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask
didFinishDownloadingToURL:(NSURL *)location {
}
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffset expectedTotalBytes:(int64_t)expectedTotalBytes {
}
NSURLSessionStreamDelegate
NSURLSessionDataDelegate, NSURLSessionDownloadDelegate,NSURLSessionStreamDelegate 三个代理都是继承自NSURLSessionTaskDelegate的代理,NSURLSessionTaskDelegate继承自NSURLSessionDelegate
网络请求数据信息——NSURLResponse
请求方式
- GET
- POST
两种请求方式比较:
相同点:都能给服务器传输数据
不同点:
1、给服务器传输数据的方式:
GET:通过网址字符串。
POST:通过data
2、传输数据的⼤小:
GET:网址字符串最多255字节。
POST:使用NSData,容量超过1G
3、安全性:
GET:所有传输给服务器的数据,显示在网址里,类似于密码的明文输入,直接可见。
POST:数据被转成NSData(二进制数据),类似于密码的密文输入,无法直接读取。
连接方式
- 同步连接: 程序容易出现卡死现象
- 异步连接: 等待数据返回。
异步联接有两种实现⽅式: 设置代理,接收数据;实现block
使用NSURLSession进行网络请求步骤
基本类介绍完来看一下具体使用。
1 创建一个session,创建session时指定sessionconfig
2 由session创建子类task
3 task调用resume方法,请求网络
NSURLSession *session = [NSURLSession sessionWithConfiguration:config];
NSURL *url = [NSURL URLWithString:@"http://xxx.34.43.000:8000/login"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"POST";
NSDictionary *dic = @{
@"biz":@{
@"username":@"xxff",
@"device_id" : @"d41d8cd98f00b204e9800998ecf8427e",
@"password" : @"xxxxx"
},
};
NSData *paramData = [NSJSONSerialization dataWithJSONObject:dic options:NSJSONWritingPrettyPrinted error:nil];
NSString *paramStr = [[NSString alloc] initWithData:paramData encoding:NSUTF8StringEncoding];
paramStr = [NSString stringWithFormat:@"xmas-json=%@", paramStr];
request.HTTPBody = [paramStr dataUsingEncoding:NSUTF8StringEncoding];
NSURLSessionDataTask *sessionDataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if (error) {
NSLog(@"222Error: %@", error);
} else {
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
NSLog(@"11%@", dict);
}
}];
[sessionDataTask resume];
各个子类对应不同的使用场景创建方法可以参考API。如果使用block回调创建task,那么设置的代理将无效。