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源码学习》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

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

颠覆式创新:移动互联网时代的生存法则

颠覆式创新:移动互联网时代的生存法则

李善友 / 机械工业出版社 / 2015-3-1

为什么把每件事情都做对了,仍有可能错失城池?为什么无人可敌的领先企业,却在一夜之间虎落平阳?短短三年间诺基亚陨落,摩托罗拉以区区29亿美元出售给联想,芯片业霸主英特尔在移动芯片领域份额几乎为零,风光无限的巨头转眼成为被颠覆的恐龙,默默无闻的小公司一战成名迅速崛起,令人瞠目结舌的现象几乎都能被“颠覆式创新”法则所解释。 颠覆式创新教你在新的商业竞争中“换操作系统”而不是“打补丁”,小公司用破坏......一起来看看 《颠覆式创新:移动互联网时代的生存法则》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

MD5 加密
MD5 加密

MD5 加密工具

html转js在线工具
html转js在线工具

html转js在线工具