• AFNetWorking源码详解(二)


    来源:Yuzeyang 

    链接:http://zeeyang.com/2016/03/15/AFNetWorking-two/

    AFHTTPSessionManager继承于AFURLSessionManager,提供了更方便的HTTP请求方法,包括了GET、POST、PUT、PATCH、DELETE这五种方式,并且AF鼓励我们在AFHTTPSessionManager再进行一次封装来满足我们自己的业务需求


    在开始的地方,AF一直提醒到一个属性baseURL,这个变量你可以在进一步封装的时候,将baseURL写成你自己的HTTP请求原始地址,比如

    + (NSURL *)baseURL {

        return [NSURL URLWithString:kBaseURLString];

    }

    在对baseURL进行拼接的时候,也需要注意一下几点,防止出现请求的URL出现问题

    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/

    在初始化的方法里面,我们看到这个方法

    - (instancetype)initWithBaseURL:(nullable NSURL *)url;

    - (instancetype)initWithBaseURL:(nullable NSURL *)url

               sessionConfiguration:(nullable NSURLSessionConfiguration *)configuration NS_DESIGNATED_INITIALIZER;

    NS_DESIGNATED_INITIALIZER的作用是什么呢?

    指定的构造器通过发送初始化消息到父类来保证object被完全初始化,指定构造器有以下几个规则:

    1.指定构造器必须调用父类的指定构造器

    2.任何一个便利构造器必须调用最终指向指定构造器的其他构造器

    3.具有指定构造器的类必须实现父类的所有指定构造器

    - (instancetype)init {

        // 指向- [initWithBaseURL:]

       return [self initWithBaseURL:nil];

    }

    - (instancetype)initWithBaseURL:(NSURL *)url {

        // 指向- [initWithBaseURL:sessionConfiguration:]

        return [self initWithBaseURL:url sessionConfiguration:nil];

    }

    - (instancetype)initWithSessionConfiguration:(NSURLSessionConfiguration *)configuration {

        // 指向- [initWithBaseURL:sessionConfiguration:]

        return [self initWithBaseURL:nil sessionConfiguration:configuration];

    }

    - (instancetype)initWithBaseURL:(NSURL *)url

               sessionConfiguration:(NSURLSessionConfiguration *)configuration

    {

        // 调用父类的- [initWithSessionConfiguration:]

        self = [super initWithSessionConfiguration:configuration];

        if (!self) {

            return nil;

        }

        // baseURL赋值,AFHTTPRequestSerializer和AFJSONResponseSerializer序列化

        

        return self;

    }

    DEPRECATED_ATTRIBUTE这个相信大家见得比较多了,字面意思就是这个API不建议开发者再使用了,再使用时,会出现编译警告

    - (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;


    下面POST、GET、PUT、PATCH、DELETE方法传参基本都是大同小异

    URLString表示请求的URL,parameters表示客户端请求内容的存储器,progress表示请求的进度,constructingBodyWithBlock里面只有一个formData用来拼接到HTTP的请求体,success表示请求成功后的block回调,failure表示请求失败的block回调

    那么这几个请求有什么区别呢?

    1、POST请求是向服务端发送数据的,用来更新资源信息,它可以改变数据的种类等资源

    2、GET请求是向服务端发起请求数据,用来获取或查询资源信息

    3、PUT请求和POST请求很像,都是发送数据的,但是PUT请求不能改变数据的种类等资源,它只能修改内容

    4、DELETE请求就是用来删除某个资源的

    5、PATCH请求和PUT请求一样,也是用来进行数据更新的,它是HTTP verb推荐用于更新的

    在实际开发过程中,我们还是使用POST和GET请求是最多的


    在请求实现的部分,都是调用了-[dataTaskWithHTTPMethod:URLString:parameters:uploadProgress:downloadProgress:success:failure]方法创建NSURLSessionDataTask对象

    传参的内容基本都是和上一层方法一样,method指的就是请求的类型

    - (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) {

            // 失败成功处理

        }];

        return dataTask;

    }

  • 相关阅读:
    hdu4612 无向图中随意加入一条边后使桥的数量最少 / 无向图缩点+求树的直径
    Python 之 安装模块的多种方法
    开源项目Universal Image Loader for Android 说明文档 (1) 简单介绍
    IDEA下使用Jetty进行Debug模式调试
    离线安装Cloudera Manager5.3.4与CDH5.3.4(一)
    让你提前认识软件开发(38):完毕第一个新需求
    Windows App开发之经常使用控件与应用栏
    【剑指Offer学习】【面试题58:二叉树的下一个结点】
    【Win】编写简单的bat文件
    【Linux】MySQL解压版安装及允许远程访问
  • 原文地址:https://www.cnblogs.com/fengmin/p/5659118.html
Copyright © 2020-2023  润新知