AFNetworking源码学习

栏目: IOS · 发布时间: 5年前

内容简介:AFNetWorking是使用AFNetWorking主要分为5个部分。整个AFNetWorking组织结构如下:

AFNetworking源码学习

简介

AFNetWorking是使用 Objective-c 开发iOS程序主流的网络请求开源库。

AFNetworking组织结构

AFNetWorking主要分为5个部分。 NSURLSessionReachabilitysecuritySerializationUIKit 。其中NSURLSession是整个网络请求开源库的 灵魂 ,对外提供了丰富的网络请求接口。包括 GETPOSTHEADPUTDELETE ,与及文件上传的接口。

整个AFNetWorking组织结构如下:

AFNetworking源码学习

源码解读

1.NSURLSession

NSURLSession包括 AFURLSessionManagerAFHTTPSessionManager ,AFHTTPSessionManager继承了AFURLSessionManager,对外提供了网络请求的接口。我们最常使用的 GETPOST 接口,底层都调用了

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

整个方法的实现如下:

- (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) {
            dispatch_async(self.completionQueue ?: dispatch_get_main_queue(), ^{
                failure(nil, serializationError);
            });
        }

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

文件上传的接口例外,文件上传涉及到数据分片的问题,使用的是一个叫`- (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`接口,这个接口的全部实现如下:
- (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) {
            dispatch_async(self.completionQueue ?: dispatch_get_main_queue(), ^{
                failure(nil, serializationError);
            });
        }

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

AFURLSessionManager

AFURLSessionManager是整个网络请求框架的核心。

创建了 url_session_manager_creation_queueurl_session_manager_processing_queue

url_session_manager_completion_group,这三个都是单例的形式。

AFURLSessionManager是以 串行队列 的方式进行session管理的。安全策略使用的是默认策略。`- (NSURLSessionDataTask )dataTaskWithRequest:(NSURLRequest )request

uploadProgress:(nullable void (^)(NSProgress *uploadProgress)) uploadProgressBlock
                         downloadProgress:(nullable void (^)(NSProgress *downloadProgress)) downloadProgressBlock
                        completionHandler:(nullable void (^)(NSURLResponse *response, id _Nullable responseObject,  NSError * _Nullable error))completionHandler`以安全的方式,创建了一个dataTask,最后加入到mutableTask的**NSMutableDictionary**中。

AFURLSessionManager是AFHTTPSessionManager的基础,对AFHTTPSessionManager提供了 downloadTaskuploadTaskdataTask 等等的封装。

2.AFNetworkReachabilityManager

AFNetworkReachabilityManager监测网络状态。方法如下:

static AFNetworkReachabilityStatus AFNetworkReachabilityStatusForFlags(SCNetworkReachabilityFlags flags) {
    BOOL isReachable = ((flags & kSCNetworkReachabilityFlagsReachable) != 0);
    BOOL needsConnection = ((flags & kSCNetworkReachabilityFlagsConnectionRequired) != 0);
    BOOL canConnectionAutomatically = (((flags & kSCNetworkReachabilityFlagsConnectionOnDemand ) != 0) || ((flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) != 0));
    BOOL canConnectWithoutUserInteraction = (canConnectionAutomatically && (flags & kSCNetworkReachabilityFlagsInterventionRequired) == 0);
    BOOL isNetworkReachable = (isReachable && (!needsConnection || canConnectWithoutUserInteraction));

    AFNetworkReachabilityStatus status = AFNetworkReachabilityStatusUnknown;
    if (isNetworkReachable == NO) {
        status = AFNetworkReachabilityStatusNotReachable;
    }
#if    TARGET_OS_IPHONE
    else if ((flags & kSCNetworkReachabilityFlagsIsWWAN) != 0) {
        status = AFNetworkReachabilityStatusReachableViaWWAN;
    }
#endif
    else {
        status = AFNetworkReachabilityStatusReachableViaWiFi;
    }

    return status;
}

根据传入的 SCNetworkReachabilityFlags 标志进行判断,返回对应的网络状态。

3.AFSecurityPolicy

AFSecurityPolicy,网络请求的安全策略。该类提供了三种安全策略:

typedef NS_ENUM(NSUInteger, AFSSLPinningMode) {
    AFSSLPinningModeNone,
    AFSSLPinningModePublicKey,
    AFSSLPinningModeCertificate,
};

默认的安全策略是 AFSSLPinningModeNone ,我们可以根据需要设置对应的安全策略。

开发中实际的设置栗子如下:

- (void)setupSecurityPolicy {
    
    AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModePublicKey];
    [securityPolicy setAllowInvalidCertificates:YES];
    [securityPolicy setValidatesDomainName:YES];
    
    self.sessionManager.securityPolicy = securityPolicy;
}

我们当时使用的是 SSL 对传输的数据进行加密,来达到数据的安全传输。

4.AFURLRequestSerialization

里面是对客户端发起的请求的序列化。

- (NSURLRequest *)requestBySerializingRequest:(NSURLRequest *)request
                               withParameters:(id)parameters
                                        error:(NSError *__autoreleasing *)error
{
    NSParameterAssert(request);

    NSMutableURLRequest *mutableRequest = [request mutableCopy];

    [self.HTTPRequestHeaders enumerateKeysAndObjectsUsingBlock:^(id field, id value, BOOL * __unused stop) {
        if (![request valueForHTTPHeaderField:field]) {
            [mutableRequest setValue:value forHTTPHeaderField:field];
        }
    }];

    NSString *query = nil;
    if (parameters) {
        if (self.queryStringSerialization) {
            NSError *serializationError;
            query = self.queryStringSerialization(request, parameters, &serializationError);

            if (serializationError) {
                if (error) {
                    *error = serializationError;
                }

                return nil;
            }
        } else {
            switch (self.queryStringSerializationStyle) {
                case AFHTTPRequestQueryStringDefaultStyle:
                    query = AFQueryStringFromParameters(parameters);
                    break;
            }
        }
    }

    if ([self.HTTPMethodsEncodingParametersInURI containsObject:[[request HTTPMethod] uppercaseString]]) {
        if (query && query.length > 0) {
            mutableRequest.URL = [NSURL URLWithString:[[mutableRequest.URL absoluteString] stringByAppendingFormat:mutableRequest.URL.query ? @"&%@" : @"?%@", query]];
        }
    } else {
        // #2864: an empty string is a valid x-www-form-urlencoded payload
        if (!query) {
            query = @"";
        }
        if (![mutableRequest valueForHTTPHeaderField:@"Content-Type"]) {
            [mutableRequest setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
        }
        [mutableRequest setHTTPBody:[query dataUsingEncoding:self.stringEncoding]];
    }

    return mutableRequest;
}

对请求参数进行拼接,序列化,设置request的 Content-Type ,然后把序列化后的参数设置到 HTTPBody 中。

还有对应的序列化类 AFJSONRequestSerializer & AFPropertyListRequestSerializer ,可以把请求参数根据 Content-Type 序列化成 application/json 或者 application/x-plist 格式。

5.AFURLResponseSerialization

response序列化就是把响应数据使用数据解析器解析成对应的格式。 AFURLResponseSerialization 提供的解析器有:

  1. AFJSONResponseSerializer -> application/json / text/json / text/javascript
  2. AFXMLParserResponseSerializer -> application/xml / text/xml
  3. AFPropertyListResponseSerializer -> application/x-plist
  4. AFImageResponseSerializer -> image/jpeg / image/gif / image/png ,这三种是常用的,还有其他好几种,可以到源码中查看。
  5. AFCompoundResponseSerializer 合成解析器,是上面几种的集合。

以上所述就是小编给大家介绍的《AFNetworking源码学习》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

深入浅出Node.js

深入浅出Node.js

朴灵 / 人民邮电出版社 / 2013-12-1 / CNY 69.00

本书从不同的视角介绍了 Node 内在的特点和结构。由首章Node 介绍为索引,涉及Node 的各个方面,主要内容包含模块机制的揭示、异步I/O 实现原理的展现、异步编程的探讨、内存控制的介绍、二进制数据Buffer 的细节、Node 中的网络编程基础、Node 中的Web 开发、进程间的消息传递、Node 测试以及通过Node 构建产品需要的注意事项。最后的附录介绍了Node 的安装、调试、编码......一起来看看 《深入浅出Node.js》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具