如何使用NSURLConnection进行网络请求
NSURLConnection是iOS中最经典的网络请求方案。虽然在苹果公司推出NSURLSession后已经不推荐使用NSURLConnection了(NSURLConnection在iOS 9被宣布弃用),但是在一些早先构建的项目和框架中可能仍然使用了NSURLConnection的技术,所以了解NSURLConnection的基本操作仍然是有必要的。使用NSURLConnection发送请求通常需要使用以下类:
1)NSURL,主要用于创建网络请求地址。一个NSURL对象代表了一个表示远程服务器资源或者本地文件的URL。开发者可以直接使用经过UTF-8编码后的字符串创建一个NSURL:
+URLWithString:
-initWithString:
2)NSURLRequest,代表网络请求对象。它包含了发送一个请求所需要的一系列信息,如NSURL对象、请求方式、请求体、请求头等。使用NSURL对象创建NSURLRequest对象:
+(instancetype)requestWithURL:(NSURL*)URL
+(instancetype)requestWithURL(NSURL*)URLcachePolicy(NSURLRequestCachePolicy)cachePolicytimeoutInterval:(NSTimeInterval)timeoutInterval
3)NSURLConnection,作为CoreFoundation/CFNetwork框架的API之上的一个抽象,在2003年随着第一版的Safari就发布了。它作为iOS 7之前的网络基础架构,可以发送同步或异步请求,可以直接接收数据也可以使用代理监听请求。
NSURLConnection、NSURL、NSURLRequest之间的关系如图所示。
三者关系
NSURLConnection的使用步骤如下:
1)创建一个NSURL对象,用于设置请求路径。
2)创建一个NSURLRequest对象,并设置请求头、请求体等请求参数。
3)创建一个NSURLResponse对象用于接收响应数据,一般使用NSURLResponse的子类NSHTTPURLResponse。
4)使用NSURLConnection发送同步或异步请求。
下面的代码将演示如何使用NSURLConnection发送请求并获得数据。
(1)同步GET请求方法
+ (nullable NSData *)sendSynchronousRequest:(NSURLRequest *)request returningResponse:(NSURLResponse * _Nullable * _Nullable)response error:(NSError **)error;
示例代码如下:
- (void)connectionSyncGet{ /*创建NSURL对象*/ NSURL *url = [NSURL URLWithString:IMAGEURL]; /*创建请求对象,默认为GET请求*/ NSURLRequest *request = [NSURLRequest requestWithURL:url]; /*创建请求响应对象*/ NSHTTPURLResponse *response = nil; NSError *error = nil; /*发送请求,同步请求会阻塞当前线程*/ NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error]; /*解析返回的数据*/ _image = [UIImage imageWithData:data]; /*显示图片*/ [self changeBg]; } - (void)changeBg{ self.view.layer.contents = (id)_image.CGImage; }
(2)异步POST请求方法
+ (void)sendAsynchronousRequest:(NSURLRequest*) request queue:(NSOperationQueue*) queue completionHandler:(void (^)(NSURLResponse* _Nullable response, NSData* _Nullable data, NSError* _Nullable connectionError)) handler;
示例代码如下:
- (void)connectionAsyncPost{ NSURL *url = [NSURL URLWithString:IMAGEURL]; /*创建请求对象*/ NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; /*设置请求方式为POST*/ request.HTTPMethod = @"POST"; /*设置请求体,在请求体中设置参数*/ request.HTTPBody = [@"username=520it&pwd=520&type=JSON" dataUsingEncoding:NSUTF8StringEncoding]; /*设置请求超时*/ request.timeoutInterval = 15; /*设置请求头*/ [request setValue:@"iOS" forHTTPHeaderField:@"User-Agent"]; /*发送请求*/ [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) { NSLog(@"NSThread = %@",[NSThread currentThread]); if (connectionError) { NSLog(@"error = %@",connectionError.userInfo); }else{ /*解析返回的数据*/ _image = [UIImage imageWithData:data]; /*显示图片*/ [self changeBg]; } }] }
(3)NSURLConnectionDelegate的使用
可以使用NSURLConnectionDelegate监听网络请求的响应。示例代码如下:
- (void)connectGETDelegate{ /*创建NSURL对象*/ NSURL *url = [NSURL URLWithString:IMAGEURL]; /*创建请求对象,默认为GET请求*/ NSURLRequest *request = [NSURLRequest requestWithURL:url]; /*设置代理*/ [NSURLConnection connectionWithRequest:request delegate:self]; } /*当接收到服务器响应的时候调用。第一个参数connection:监听的是哪个NSURLConnection对象;第二个参数response:接收到的服务器返回的响应头信息*/ - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{ _imageData = [NSMutableData data]; } /*当接收到数据的时候调用,该方法会被调用多次。第一个参数connection:监听的是哪个NSURLConnection对象;第二个参数data:本次接收到的服务端返回的二进制数据(可能是片段)*/ - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{ [_imageData appendData:data]; }
如何使用NSURLSession进行网络请求
在2013年的WWDC上,苹果公司推出了NSURLConnection的替代方案:NSURLSession。和NSURLConnection一样,NSURLSession指的也不仅是同名类NSURLSession,它还包括一系列相关联的类。NSURLSession包括了与之前相同的组件:NSURLRequest与NSURLCache,但是将NSURLConnection替换成了NSURLSession、NSURLSessionConfiguration及NSURLSessionTask的3个子类:NSURLSessionDataTask、NSURLSessionUploadTask、NSURLSessionDownloadTask。
与NSURLConnection相比,NSURLSession最直接的改进就是可以配置每个session的缓存、协议、cookie,以及证书策略(CredentialPolicy),甚至跨进程共享这些信息。这将允许程序和网络基础框架之间相互独立,不会发生干扰。每个NSURLSession对象都由一个NSURLSessionConfiguration对象进行初始化,后者指定了刚才提到的那些策略以及一些用来增强移动设备上性能的新选项。
NSURLSessionTask负责处理数据的加载以及文件的数据在客户端与服务器之间的上传和下载。它是一个抽象类,一般使用其子类:NSURLSessionDataTask、NSURLSessionUploadTask、NSURLSessionDownloadTask。这3个子类封装了现代程序3个最基本的网络任务:获取数据(如JSON或者XML),上传文件和下载文件。
NSURLSession相关类的关系如图所示。
NSURLSession相关类的关系
如何使用NSURLSession像NSURLConnection那样发送一个请求呢?基本步骤如下:
1)创建NSURLSessionConfiguration对象对NSURLSession进行配置。
2)创建NSURLSession对象。
3)利用上一步创建好的NSURLSession对象创建NSURLSessionTask的子类对象。
4)执行请求任务。
下面的示例展示了NSURLSession的基本用法,代码如下:
- (void)sessionGet{ /*创建NSURL对象*/ NSURL *url = [NSURL URLWithString:IMAGEURL]; /*创建请求对象,默认为GET请求*/ NSURLRequest *request = [NSURLRequest requestWithURL:url]; /*创建配置*/ NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration]; /*创建NSURLSession对象*/ NSURLSession *session = [NSURLSession sessionWithConfiguration:config]; /*创建任务*/ NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { if (error) { return; } /*解析返回的数据*/ _image = [UIImage imageWithData:data]; /*显示图片,注意!此时是异步线程需要在主线程中显示图片*/ [self changeBg]; }]; [task resume]; }