系列:iOS开发-网络请求

来源:互联网 发布:windows正版激活工具 编辑:程序博客网 时间:2024/05/22 16:47

系列:iOS开发-网络请求

我们的目标是开发应用,那么或多或少的我们就会有网络请求的需求,比如我们在开发的时候有用户登录,比如我们写一个音乐软件,我们要获取音乐列表,获取音乐来播放,再复杂点的,我们可能会写一个聊天类的软件,需要即时获取聊天消息…

所以,网络请求对于开发来说肯定是必不可少的.
那么什么是网络请求?
简单的来说,我们在浏览器输入一串类似于http://www.baidu.com 我们就能够访问到百度,这个就是一个网络请求了,
虽然是一个简单的地址,但是它其实也包含了很多信息,

首先 http:// 这是一个协议,HTTP协议通常承载于TCP协议之上,有时也承载于TLS或SSL协议层之上,这个时候,就成了我们常说的HTTPS。如下图所示:
这里写图片描述
这里我也不做过多的解释,我们大学都有学过TCP UDP等…
HTTP协议是客户端发起请求,服务器回送响应,然后建立彼此的链接,
至于是哪一个服务器,取决于ip地址或者域名,也就是上面的baidu.com,
在这之后是端口号,文件路径,参数等等….

当然这些只是客户端和服务端链接的路径信息,我们在做网络请求的时候还有方式,
标准Http协议支持六种请求方法,即:
1、GET
2、POST
3、PUT
4、Delete
5、HEAD
6、Options
当然我们在应用开发的时候我们用到更多的是GET\POST,大家可以百度一下这些方式的区别.

对于iOS开发来说,系统是有给我们提供网络请求库的
对于老一点的开发人员来说,可能会很熟悉的是这个
NSURLConnection,很多老版本的iOS项目都会使用这个来封装自己应用的网络库,它有集成的block形式,也有delegate形式,我们可以获取到请求开始,对请求到的数据进行追加,完成请求,或者请求错误等代理的分布处理,也可以直接通过block直接异步获取回调结果,是成功还是失败,前者可操作性更多,后者更简洁,
比如我们在请求开始的时候做拦截,前者就更好做到,后者就不容易了.
但是在iOS9的时候这个网络请求已经被系统所废弃了,用了其他的来取代,
这里我们就简单的举个使用NSURLConnection的例子

NSURL *url = [NSURL URLWithString:@"https://api.dolry.cn/dongting/Api/Weather"];//URL地址    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];    [request setHTTPMethod:@"post"];//请求方式    [request setValue:@"application/octet-stream" forHTTPHeaderField:@"Content-Type"];//头部信息    [request setHTTPBody:[@"province=上海&city=上海" dataUsingEncoding:NSUTF8StringEncoding]];//参数内容    [request setTimeoutInterval:20.0];//超时时间    __weak typeof(self)weakSelf = self;    NSOperationQueue *queue=[NSOperationQueue mainQueue];    [NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {        NSDictionary * result = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];//解析结果        NSLog(@"%@",[result descriptionWithLocale:nil]);        weakSelf.textView.text = [result descriptionWithLocale:nil];//显示    }];

这里写图片描述
我们可以看到一次请求会有很多东西,比如地址,比如方式,比如参数,比如头部信息,比如超时时间等等,当然其中有的是可选的,这个需要根据实际环境来区别对待.
系统的封装算是比较完善了,当然对于一些特殊的需求我们可以不适用block的形式,我们可以通过代理来完成

@protocol NSURLConnectionDataDelegate <NSURLConnectionDelegate>@optional- (nullable NSURLRequest *)connection:(NSURLConnection *)connection willSendRequest:(NSURLRequest *)request redirectResponse:(nullable NSURLResponse *)response;//将要发送请求- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response;//已经完成响应- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data;//接收到的数据- (void)connectionDidFinishLoading:(NSURLConnection *)connection;//完成请求@end

我列举了几个常用的代理,当然远不止这些,我们可以使用这些来进一步进行特殊的操作,

系统更新到iOS9的时代,上面的NSURLConnection就已经被废弃了,取而代之的是新的框架
NSURLSession,但是它并不是iOS9才出来的,在iOS7的时候就已经有了,只是在iOS9的时候完全取代了NSURLConnection
相较于来说其优势明显
NSURLSession 的优势

  • NSURLSession 支持 http2.0 协议
  • 在处理下载任务的时候可以直接把数据下载到磁盘
  • 支持后台下载|上传
  • 同一个 session 发送多个请求,只需要建立一次连接(复用了TCP)
  • 提供了全局的 session 并且可以统一配置,使用更加方便
  • 下载的时候是多线程异步处理,效率更高
    这里写图片描述
    我们可以看到系统做了很多的内容,
    NSURLSessionTask 是一个抽象类,如果要使用那么只能使用它的子类,这个我们可以不管,
    其下面的子类SURLSessionDataTask,可以用来处理一般的网络请求,如 GET | POST 请求等
    NSURLSessionDataTask 有一个子类为 NSURLSessionUploadTask,用于处理上传请求的时候有优势
    NSURLSessionDownloadTask,主要用于处理下载请求,有很大的优势
@interface NSURLSession (NSURLSessionAsynchronousConvenience)/* * data task convenience methods.  These methods create tasks that * bypass the normal delegate calls for response and data delivery, * and provide a simple cancelable asynchronous interface to receiving * data.  Errors will be returned in the NSURLErrorDomain,  * see <Foundation/NSURLError.h>.  The delegate, if any, will still be * called for authentication challenges. */- (NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)request completionHandler:(void (^)(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error))completionHandler;- (NSURLSessionDataTask *)dataTaskWithURL:(NSURL *)url completionHandler:(void (^)(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error))completionHandler;/* * upload convenience method. */- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request fromFile:(NSURL *)fileURL completionHandler:(void (^)(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error))completionHandler;- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request fromData:(nullable NSData *)bodyData completionHandler:(void (^)(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error))completionHandler;/* * download task convenience methods.  When a download successfully * completes, the NSURL will point to a file that must be read or * copied during the invocation of the completion routine.  The file * will be removed automatically. */- (NSURLSessionDownloadTask *)downloadTaskWithRequest:(NSURLRequest *)request completionHandler:(void (^)(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error))completionHandler;- (NSURLSessionDownloadTask *)downloadTaskWithURL:(NSURL *)url completionHandler:(void (^)(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error))completionHandler;- (NSURLSessionDownloadTask *)downloadTaskWithResumeData:(NSData *)resumeData completionHandler:(void (^)(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error))completionHandler;@end

发送网络请求很简单,

    //NSURLSession    NSURL *url = [NSURL URLWithString:@"https://api.dolry.cn/dongting/Api/Weather"];//URL地址    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];    [request setHTTPMethod:@"post"];//请求方式    [request setValue:@"application/octet-stream" forHTTPHeaderField:@"Content-Type"];//头部信息    [request setHTTPBody:[@"province=上海&city=上海" dataUsingEncoding:NSUTF8StringEncoding]];//参数内容    [request setTimeoutInterval:20.0];//超时时间    NSURLSession *session = [NSURLSession sharedSession];    __weak typeof(self)weakSelf = self;    NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {        NSDictionary * result = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];//解析结果        NSLog(@"%@",[result descriptionWithLocale:nil]);        dispatch_async(dispatch_get_main_queue(), ^{            weakSelf.textView.text = [result descriptionWithLocale:nil];//显示        });    }];//封装请求    [task resume];//开始请求

类似于上面的NSURLConnection网路请求,当然我们也可以使用NSURLSession的代理
我们要注意的是设置代理之后的强引用问题
NSURLSession 对象在使用的时候,如果设置了代理,那么 session 会对代理对象保持一个强引用,在合适的时候应该主动进行释放
可以在控制器调用 viewDidDisappear 方法的时候来进行处理,可以通过调用 invalidateAndCancel 方法或者是 finishTasksAndInvalidate 方法来释放对代理对象的强引用

  • invalidateAndCancel 方法直接取消请求然后释放代理对象
  • finishTasksAndInvalidate 方法等请求完成之后释放代理对象。
  • [self.session finishTasksAndInvalidate];

我们看看运行结果
这里写图片描述

另外我们还要注意的是这个
- (void)suspend;
- (void)resume;
作为新的框架,多出来两个方法,暂停和恢复(开始)并不是没有意义多次一举的,在上面的例子中你获取看到了resume,感觉很麻烦没有必要,但是你试着想一下,如果我们写的是一个网络下载呢?我们需要下载一个大文件,中途想要暂停下载,过一端时间再恢复呢?有了上面的方法,轻而易举是不是,我们把下载的所有封装好,我们只要关注下载的进程,不需要关注中间发生的事情即可…

当然,作为一个开发人员来说,你可能在刚刚开始学习iOS开发的时候就听过了AFNetworking这个三方框架了,是的,不可否认,其封装的很完整,帮我们做了很多事情,我们只要简单的调用接口即可,类似这样:

    //AFNetworking    NSString *urlString = @"https://api.dolry.cn/dongting/Api/Weather";    NSDictionary *parameters = @{@"province":@"上海",                                 @"city":@"上海"};    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];    manager.responseSerializer = [AFHTTPResponseSerializer serializer];    __weak typeof(self)weakSelf = self;    [manager POST:urlString parameters:parameters progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {        NSDictionary * result = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers error:nil];//解析结果        NSLog(@"%@",[result descriptionWithLocale:nil]);        dispatch_async(dispatch_get_main_queue(), ^{            weakSelf.textView.text = [result descriptionWithLocale:nil];//显示        });    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {        NSLog(@"%@",error.description);    }];

简单的,我们设置好地址和参数即可,调用相应的接口,就跟在浏览器输入了一串地址一样,所有的都不需要另行处理了,
其封装了各种请求的方式(下面的可以不看..,可以自己到框架中去学习)

/** Creates and runs an `NSURLSessionDataTask` with a `GET` request. @param URLString The URL string used to create the request URL. @param parameters The parameters to be encoded according to the client request serializer. @param success A block object to be executed when the task finishes successfully. This block has no return value and takes two arguments: the data task, and the response object created by the client response serializer. @param failure A block object to be executed when the task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the data task and the error describing the network or parsing error that occurred. @see -dataTaskWithRequest:completionHandler: */- (nullable NSURLSessionDataTask *)GET:(NSString *)URLString                   parameters:(nullable id)parameters                      success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success                      failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure DEPRECATED_ATTRIBUTE;/** Creates and runs an `NSURLSessionDataTask` with a `GET` request. @param URLString The URL string used to create the request URL. @param parameters The parameters to be encoded according to the client request serializer. @param downloadProgress A block object to be executed when the download progress is updated. Note this block is called on the session queue, not the main queue. @param success A block object to be executed when the task finishes successfully. This block has no return value and takes two arguments: the data task, and the response object created by the client response serializer. @param failure A block object to be executed when the task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the data task and the error describing the network or parsing error that occurred. @see -dataTaskWithRequest:uploadProgress:downloadProgress:completionHandler: */- (nullable NSURLSessionDataTask *)GET:(NSString *)URLString                            parameters:(nullable id)parameters                              progress:(nullable void (^)(NSProgress *downloadProgress))downloadProgress                               success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success                               failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure;/** Creates and runs an `NSURLSessionDataTask` with a `HEAD` request. @param URLString The URL string used to create the request URL. @param parameters The parameters to be encoded according to the client request serializer. @param success A block object to be executed when the task finishes successfully. This block has no return value and takes a single arguments: the data task. @param failure A block object to be executed when the task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the data task and the error describing the network or parsing error that occurred. @see -dataTaskWithRequest:completionHandler: */- (nullable NSURLSessionDataTask *)HEAD:(NSString *)URLString                    parameters:(nullable id)parameters                       success:(nullable void (^)(NSURLSessionDataTask *task))success                       failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure;/** Creates and runs an `NSURLSessionDataTask` with a `POST` request. @param URLString The URL string used to create the request URL. @param parameters The parameters to be encoded according to the client request serializer. @param success A block object to be executed when the task finishes successfully. This block has no return value and takes two arguments: the data task, and the response object created by the client response serializer. @param failure A block object to be executed when the task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the data task and the error describing the network or parsing error that occurred. @see -dataTaskWithRequest:completionHandler: */- (nullable NSURLSessionDataTask *)POST:(NSString *)URLString                    parameters:(nullable id)parameters                       success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success                       failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure DEPRECATED_ATTRIBUTE;/** Creates and runs an `NSURLSessionDataTask` with a `POST` request. @param URLString The URL string used to create the request URL. @param parameters The parameters to be encoded according to the client request serializer. @param uploadProgress A block object to be executed when the upload progress is updated. Note this block is called on the session queue, not the main queue. @param success A block object to be executed when the task finishes successfully. This block has no return value and takes two arguments: the data task, and the response object created by the client response serializer. @param failure A block object to be executed when the task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the data task and the error describing the network or parsing error that occurred. @see -dataTaskWithRequest:uploadProgress:downloadProgress:completionHandler: */- (nullable NSURLSessionDataTask *)POST:(NSString *)URLString                             parameters:(nullable id)parameters                               progress:(nullable void (^)(NSProgress *uploadProgress))uploadProgress                                success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success                                failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure;/** Creates and runs an `NSURLSessionDataTask` with a multipart `POST` request. @param URLString The URL string used to create the request URL. @param parameters The parameters to be encoded according to the client request serializer. @param block A block that takes a single argument and appends data to the HTTP body. The block argument is an object adopting the `AFMultipartFormData` protocol. @param success A block object to be executed when the task finishes successfully. This block has no return value and takes two arguments: the data task, and the response object created by the client response serializer. @param failure A block object to be executed when the task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the data task and the error describing the network or parsing error that occurred. @see -dataTaskWithRequest:completionHandler: */- (nullable NSURLSessionDataTask *)POST:(NSString *)URLString                    parameters:(nullable id)parameters     constructingBodyWithBlock:(nullable void (^)(id <AFMultipartFormData> formData))block                       success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success                       failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure DEPRECATED_ATTRIBUTE;/** Creates and runs an `NSURLSessionDataTask` with a multipart `POST` request. @param URLString The URL string used to create the request URL. @param parameters The parameters to be encoded according to the client request serializer. @param block A block that takes a single argument and appends data to the HTTP body. The block argument is an object adopting the `AFMultipartFormData` protocol. @param uploadProgress A block object to be executed when the upload progress is updated. Note this block is called on the session queue, not the main queue. @param success A block object to be executed when the task finishes successfully. This block has no return value and takes two arguments: the data task, and the response object created by the client response serializer. @param failure A block object to be executed when the task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the data task and the error describing the network or parsing error that occurred. @see -dataTaskWithRequest:uploadProgress:downloadProgress:completionHandler: */- (nullable NSURLSessionDataTask *)POST:(NSString *)URLString                             parameters:(nullable id)parameters              constructingBodyWithBlock:(nullable void (^)(id <AFMultipartFormData> formData))block                               progress:(nullable void (^)(NSProgress *uploadProgress))uploadProgress                                success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success                                failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure;/** Creates and runs an `NSURLSessionDataTask` with a `PUT` request. @param URLString The URL string used to create the request URL. @param parameters The parameters to be encoded according to the client request serializer. @param success A block object to be executed when the task finishes successfully. This block has no return value and takes two arguments: the data task, and the response object created by the client response serializer. @param failure A block object to be executed when the task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the data task and the error describing the network or parsing error that occurred. @see -dataTaskWithRequest:completionHandler: */- (nullable NSURLSessionDataTask *)PUT:(NSString *)URLString                   parameters:(nullable id)parameters                      success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success                      failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure;/** Creates and runs an `NSURLSessionDataTask` with a `PATCH` request. @param URLString The URL string used to create the request URL. @param parameters The parameters to be encoded according to the client request serializer. @param success A block object to be executed when the task finishes successfully. This block has no return value and takes two arguments: the data task, and the response object created by the client response serializer. @param failure A block object to be executed when the task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the data task and the error describing the network or parsing error that occurred. @see -dataTaskWithRequest:completionHandler: */- (nullable NSURLSessionDataTask *)PATCH:(NSString *)URLString                     parameters:(nullable id)parameters                        success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success                        failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure;/** Creates and runs an `NSURLSessionDataTask` with a `DELETE` request. @param URLString The URL string used to create the request URL. @param parameters The parameters to be encoded according to the client request serializer. @param success A block object to be executed when the task finishes successfully. This block has no return value and takes two arguments: the data task, and the response object created by the client response serializer. @param failure A block object to be executed when the task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the data task and the error describing the network or parsing error that occurred. @see -dataTaskWithRequest:completionHandler: */- (nullable NSURLSessionDataTask *)DELETE:(NSString *)URLString                      parameters:(nullable id)parameters                         success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success                         failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure;

这里写图片描述

很优雅的请求方式….
当然AFNetworking不仅仅这么简单,作为一个基本上人人必会的网络框架,其包含的内容有很多,值得学习,无论是语法格式,还是异步处理,还是线程并发,还是模块分类…还是网络请求中的各个环节(会话,策略,请求,响应,编码,回调….)
这里不是对这个三方库专门做解析的,就不赘述了,网上有很多解析,或者等我之后整理出来….

当然,作为一个开发,你肯能用的是Swift语言,我们或者可以仍然使用AFNetworking,我们也可以使用该作者的另一个网络库Swift语言的Alamofire…
这里也暂且不表…

Demo地址:https://github.com/spicyShrimp/DEMO_OC

系列:iOS开发-前言+大纲
http://blog.csdn.net/spicyShrimp/article/details/62218521

1 0
原创粉丝点击