美文网首页iOS源码解读
3.0 源码解读(二)之 AFHTTPSessionManage

3.0 源码解读(二)之 AFHTTPSessionManage

作者: 老马的春天 | 来源:发表于2016-08-20 16:36 被阅读1167次

    AFHTTPSessionManager相对来说比较好理解,代码也比较短。但却是我们平时可能使用最多的类。

    AFNetworking 3.0 源码解读(一)之 AFNetworkReachabilityManager

    AFNetworking 3.0 源码解读(二)之 AFSecurityPolicy

    AFNetworking 3.0 源码解读(三)之 AFURLRequestSerialization

    AFNetworking 3.0 源码解读(四)之 AFURLResponseSerialization

    AFNetworking 3.0 源码解读(五)之 AFURLSessionManager

    前言

    AFHTTPSessionManagerAFURLSessionManager的子类,是专门为HTTP请求设计的。里边涉及到了GET,POST,PUT,DELETE 等等HTTPMehtod。因此我们要想正确的使用各种方法,就要理解每个method的含义。
    可以通过这篇文章来了解HTTP Method详细解读(GET HEAD POST OPTIONS PUT DELETE TRACE CONNECT)

    1.相对路径(relative)

    假如有一个基础路径NSURL *baseURL = [NSURL URLWithString:@"http://example.com/v1/"];我们暂时命名为baseURL.所谓 相对 肯定跟这个baseURL有关系。

    我们可以通过NSURL +URLWithString:relativeToURL:这个方法来获取一个路径,至于怎么使用,我们通过一个例子来说明:

    NSURL *baseURL = [NSURL URLWithString:@"http://example.com/v1/"];
    [NSURL URLWithString:@"foo" relativeToURL:baseURL];                  // http://example.com/v1/foo
    [NSURL URLWithString:@"foo?bar=baz" relativeToURL:baseURL];          // http://example.com/v1/foo?bar=baz
    [NSURL URLWithString:@"/foo" relativeToURL:baseURL];                 // http://example.com/foo
    [NSURL URLWithString:@"foo/" relativeToURL:baseURL];                 // http://example.com/v1/foo
    [NSURL URLWithString:@"/foo/" relativeToURL:baseURL];                // http://example.com/foo/
    [NSURL URLWithString:@"http://example2.com/" relativeToURL:baseURL]; // http://example2.com/
    

    至于 绝对路径相对路径 的定义,使用方法,优缺点,这里就不提了,大家可以自行了解。说一下为什么使用相对路径吧。

    在真实开发中,一般都会有一个线上的服务器和一下测试服务器,当然也可能多个。在ios开发中切换开发环境有好几种方法,

    1. 通过target
    2. 自定义一个字段HTTPURL,用它来控制路径
    3. 通过相对路径来切换接口

    2.GET

    // 使用GET 方法获取数据,不带进度
    - (NSURLSessionDataTask *)GET:(NSString *)URLString
                       parameters:(id)parameters
                          success:(void (^)(NSURLSessionDataTask *task, id responseObject))success
                          failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure
    {
    
        return [self GET:URLString parameters:parameters progress:nil success:success failure:failure];
    }
    // 使用GET 方法获取数据,带进度
    - (NSURLSessionDataTask *)GET:(NSString *)URLString
                       parameters:(id)parameters
                         progress:(void (^)(NSProgress * _Nonnull))downloadProgress
                          success:(void (^)(NSURLSessionDataTask * _Nonnull, id _Nullable))success
                          failure:(void (^)(NSURLSessionDataTask * _Nullable, NSError * _Nonnull))failure
    {
    
        NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"GET"
                                                            URLString:URLString
                                                           parameters:parameters
                                                       uploadProgress:nil
                                                     downloadProgress:downloadProgress
                                                              success:success
                                                              failure:failure];
    
        [dataTask resume];
    
        return dataTask;
    }
    

    3.HEAD

    // 使用HEAD 方法获取数据,
    - (NSURLSessionDataTask *)HEAD:(NSString *)URLString
                        parameters:(id)parameters
                           success:(void (^)(NSURLSessionDataTask *task))success
                           failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure
    {
        NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"HEAD" URLString:URLString parameters:parameters uploadProgress:nil downloadProgress:nil success:^(NSURLSessionDataTask *task, __unused id responseObject) {
            if (success) {
                success(task);
            }
        } failure:failure];
    
        [dataTask resume];
    
        return dataTask;
    }
    

    4.POST

    - (NSURLSessionDataTask *)POST:(NSString *)URLString
                        parameters:(id)parameters
                           success:(void (^)(NSURLSessionDataTask *task, id responseObject))success
                           failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure
    {
        return [self POST:URLString parameters:parameters progress:nil success:success failure:failure];
    }
    
    - (NSURLSessionDataTask *)POST:(NSString *)URLString
                        parameters:(id)parameters
                          progress:(void (^)(NSProgress * _Nonnull))uploadProgress
                           success:(void (^)(NSURLSessionDataTask * _Nonnull, id _Nullable))success
                           failure:(void (^)(NSURLSessionDataTask * _Nullable, NSError * _Nonnull))failure
    {
        NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"POST" URLString:URLString parameters:parameters uploadProgress:uploadProgress downloadProgress:nil success:success failure:failure];
    
        [dataTask resume];
    
        return dataTask;
    }
    

    5.上传数据

    - (NSURLSessionDataTask *)POST:(NSString *)URLString
                        parameters:(nullable id)parameters
         constructingBodyWithBlock:(nullable void (^)(id<AFMultipartFormData> _Nonnull))block
                           success:(nullable void (^)(NSURLSessionDataTask * _Nonnull, id _Nullable))success
                           failure:(nullable void (^)(NSURLSessionDataTask * _Nullable, NSError * _Nonnull))failure
    {
        return [self POST:URLString parameters:parameters constructingBodyWithBlock:block progress:nil success:success failure:failure];
    }
    
    - (NSURLSessionDataTask *)POST:(NSString *)URLString
                        parameters:(id)parameters
         constructingBodyWithBlock:(void (^)(id <AFMultipartFormData> formData))block
                          progress:(nullable void (^)(NSProgress * _Nonnull))uploadProgress
                           success:(void (^)(NSURLSessionDataTask *task, id responseObject))success
                           failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure
    {
        NSError *serializationError = nil;
        NSMutableURLRequest *request = [self.requestSerializer multipartFormRequestWithMethod:@"POST" URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters constructingBodyWithBlock:block error:&serializationError];
        if (serializationError) {
            if (failure) {
    #pragma clang diagnostic push
    #pragma clang diagnostic ignored "-Wgnu"
                dispatch_async(self.completionQueue ?: dispatch_get_main_queue(), ^{
                    failure(nil, serializationError);
                });
    #pragma clang diagnostic pop
            }
    
            return nil;
        }
    
        __block NSURLSessionDataTask *task = [self uploadTaskWithStreamedRequest:request progress:uploadProgress completionHandler:^(NSURLResponse * __unused response, id responseObject, NSError *error) {
            if (error) {
                if (failure) {
                    failure(task, error);
                }
            } else {
                if (success) {
                    success(task, responseObject);
                }
            }
        }];
    
        [task resume];
    
        return task;
    }
    

    6.PUT

    - (NSURLSessionDataTask *)PUT:(NSString *)URLString
                       parameters:(id)parameters
                          success:(void (^)(NSURLSessionDataTask *task, id responseObject))success
                          failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure
    {
        NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"PUT" URLString:URLString parameters:parameters uploadProgress:nil downloadProgress:nil success:success failure:failure];
    
        [dataTask resume];
    
        return dataTask;
    }
    

    7.PATCH

    - (NSURLSessionDataTask *)PATCH:(NSString *)URLString
                         parameters:(id)parameters
                            success:(void (^)(NSURLSessionDataTask *task, id responseObject))success
                            failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure
    {
        NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"PATCH" URLString:URLString parameters:parameters uploadProgress:nil downloadProgress:nil success:success failure:failure];
    
        [dataTask resume];
    
        return dataTask;
    }
    

    8.DELETE

    - (NSURLSessionDataTask *)DELETE:(NSString *)URLString
                          parameters:(id)parameters
                             success:(void (^)(NSURLSessionDataTask *task, id responseObject))success
                             failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure
    {
        NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"DELETE" URLString:URLString parameters:parameters uploadProgress:nil downloadProgress:nil success:success failure:failure];
    
        [dataTask resume];
    
        return dataTask;
    }
    

    9.私有方法

    - (NSURLSessionDataTask *)dataTaskWithHTTPMethod:(NSString *)method
                                           URLString:(NSString *)URLString
                                          parameters:(id)parameters
                                      uploadProgress:(nullable void (^)(NSProgress *uploadProgress)) uploadProgress
                                    downloadProgress:(nullable void (^)(NSProgress *downloadProgress)) downloadProgress
                                             success:(void (^)(NSURLSessionDataTask *, id))success
                                             failure:(void (^)(NSURLSessionDataTask *, NSError *))failure
    {
        NSError *serializationError = nil;
        NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:method URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters error:&serializationError];
        if (serializationError) {
            if (failure) {
    #pragma clang diagnostic push
    #pragma clang diagnostic ignored "-Wgnu"
                dispatch_async(self.completionQueue ?: dispatch_get_main_queue(), ^{
                    failure(nil, serializationError);
                });
    #pragma clang diagnostic pop
            }
    
            return nil;
        }
    
        __block NSURLSessionDataTask *dataTask = nil;
        dataTask = [self dataTaskWithRequest:request
                              uploadProgress:uploadProgress
                            downloadProgress:downloadProgress
                           completionHandler:^(NSURLResponse * __unused response, id responseObject, NSError *error) {
            if (error) {
                if (failure) {
                    failure(dataTask, error);
                }
            } else {
                if (success) {
                    success(dataTask, responseObject);
                }
            }
        }];
    
        return dataTask;
    }
    

    这篇文章确实比较简单,有了前几篇文章的铺垫,到了我们真正使用的时候,一切都变得那么简单自然啊.我们已经不知不觉中学到了很多知识,但有一点,知识这东西,要反复的记忆才能记住。举个例子吧 ,平时可能我们需要在web端查看json数据,当我们把参数拼接到paramter中,该怎么查看呢?

    1. 找到AFURLRequestSerialization这个.m
    2. 找到requestBySerializingRequest: withParameters: error:这个方法
    3. NSLog(@"URL: %@",mutableRequest.URL.absoluteString);

    说明

    接下来先把 AFNetworking 的分类再解析完,然后开始搭建网络框架。

    相关文章

      网友评论

        本文标题:3.0 源码解读(二)之 AFHTTPSessionManage

        本文链接:https://www.haomeiwen.com/subject/hbsisttx.html