AFNetworking 源码阅读

Posted by Abin's blog on June 10, 2017

版本:AFNetworking 3.1.0

AFNetworking 主要的几个类或协议:

  • AFURLSessionManager
  • AFHTTPSessionManager
  • AFNetworkReachabilityManager
  • AFSecurityPolicy
  • <AFURLRequestSerialization>
  • <AFURLResponseSerialization>

AFNetworking.001

AFHTTPSessionManager

AFHTTPSessionManager 是我们使用 AFNetworking 框架最外层或者是可以直接使用的类,它对于框架核心类 AFURLSessionManager 进行了常用的封装。比如设置 BaseURL 和请求序列化,AFHTTPSessionManager 重要的两个属性:

@property (readonly, nonatomic, strong, nullable) NSURL *baseURL;
@property (nonatomic, strong) AFHTTPRequestSerializer <AFURLRequestSerialization> * requestSerializer

当发送一个 GET 请求时,框架会依次调用以下三个方法:

[AFHTTPSessionManager GET:parameters:progress:success:failure:]`
[AFHTTPSessionManager dataTaskWithHTTPMethod:URLString:parameters:uploadProgress:downloadProgress:success:failure:]`
[AFURLSessionManager dataTaskWithRequest:uploadProgress:downloadProgress:completionHandler:]

第一个方法是 AFHTTPSessionManagerGETPOSTPUTPATCHDELETE 等请求做的一个封装,它们的区别就是请求方法的不同,不同的请求会传入不同的参数给第二个方法,在第二个方法中会对传入的参数进行序列化。具体的序列化方法可以查看 AFHTTPRequestSerializer。然后会把序列化之后的 NSMutableURLRequest 作为参数调用第三方方法,这时就进入了框架的核心类: AFURLSessionManager

AFURLSessionManager

AFURLSessionManager 持有一个 NSURLSession 类型的 session 属性,并作为该属性的 delegate,遵守实现了 NSURLSessionDelegate, NSURLSessionTaskDelegate, NSURLSessionDataDelegate, NSURLSessionDownloadDelegate 四个代理方法,如果任何子类继承重写这些方法,都必须先调用父类的实现。

initWithSessionConfiguration:AFURLSessionManager 的指定初始化方法,并且在session 初始化指定为其的代理:

self.session = [NSURLSession sessionWithConfiguration:self.sessionConfiguration delegate:self delegateQueue:self.operationQueue];

这样的话当一个网络请求的数据有返回或者状态被更改的时候,可以在代理方法中及时获知。AFURLSessionManagersession 属性可能会实例化多个 NSURLSessionDataTask 对象,但是 AFURLSessionManager 并不会直接维护它们,而是通过一个可变字典以 task.taskIdentifier 为 key 保存一个私有类 AFURLSessionManagerTaskDelegate 的实例,这个实例会保存这次网络请求的回调、响应数据和进度,两者是一对一的关系。当 AFURLSessionManager 所实现的协议方法被调用时,会及时更新 AFURLSessionManagerTaskDelegate 实例的数据。

在实现文件中,框架还对 NSURLSessionDataTaskresumesuspend 方法进行了 Hook,在方法执行的时候发送通知。

除此之外,AFURLSessionManager 还管理者 AFSecurityPolicyAFNetworkReachabilityManager,来保证请求的安全和查看网络连接情况,它有一个 AFJSONResponseSerializer 的实例来序列化 HTTP 响应。

AFURLRequestSerialization 和 AFURLResponseSerialization

<AFURLRequestSerialization><AFURLResponseSerialization> 只是两个协议,并且分别只有一个方法。

@protocol AFURLRequestSerialization <NSObject, NSSecureCoding, NSCopying>
- (nullable NSURLRequest *)requestBySerializingRequest:(NSURLRequest *)request
                               withParameters:(nullable id)parameters
                                        error:(NSError * _Nullable __autoreleasing *)error NS_SWIFT_NOTHROW;
@end

@protocol AFURLResponseSerialization <NSObject, NSSecureCoding, NSCopying>
- (nullable id)responseObjectForResponse:(nullable NSURLResponse *)response
                           data:(nullable NSData *)data
                          error:(NSError * _Nullable __autoreleasing *)error NS_SWIFT_NOTHROW;
@end

实现 <AFURLRequestSerialization> 协议的有 AFHTTPRequestSerializer 及其两个子类: AFJSONRequestSerializerAFPropertyListRequestSerializerAFHTTPRequestSerializer除了实现协议之外还封装了对 TTPHeader 和 HTTPBody 操作。

实现 <AFURLResponseSerialization> 协议的有 AFHTTPResponseSerializerAFJSONResponseSerializer 等数个子类。

AFHTTPResponseSerializer 有两个属性分来判断接受的 StatusCode 和 ContentType:

@property (nonatomic, copy, nullable) NSIndexSet *acceptableStatusCodes;
@property (nonatomic, copy, nullable) NSSet <NSString *> *acceptableContentTypes

AFJSONResponseSerializerAFHTTPSessionManager 类默认的响应序列化类型。

AFNetworkReachabilityManager

AFNetworkReachabilityManager 作用是监听网络,是一个比较独立的模块,可以拿出来单独使用。

指定构造方法: initWithReachability:AFNetworkReachabilityManager 会持有这个 SCNetworkReachabilityRef 属性。

调用 startMonitoring 开始监听:

- (void)startMonitoring {
    // 先停止监听
    [self stopMonitoring];
    // 不符合条件,直接返回
    if (!self.networkReachability) {
        return;
    }
    // 创建一个block作为 SCNetworkReachabilityContext 初始化的第二个参数,参数名:info 参数类型:无类型指针
    __weak __typeof(self)weakSelf = self;
    AFNetworkReachabilityStatusBlock callback = ^(AFNetworkReachabilityStatus status) {
        __strong __typeof(weakSelf)strongSelf = weakSelf;

        strongSelf.networkReachabilityStatus = status;
        if (strongSelf.networkReachabilityStatusBlock) {
            strongSelf.networkReachabilityStatusBlock(status);
        }

    };
    // 创建监听上下文
    SCNetworkReachabilityContext context = {0, (__bridge void *)callback, AFNetworkReachabilityRetainCallback, AFNetworkReachabilityReleaseCallback, NULL};
    // 设置监听回调,回调的是 AFNetworkReachabilityCallback 函数,并且callback会被作为参数一起回调
    SCNetworkReachabilitySetCallback(self.networkReachability, AFNetworkReachabilityCallback, &context);
    // 开始监听
    SCNetworkReachabilityScheduleWithRunLoop(self.networkReachability, CFRunLoopGetMain(), kCFRunLoopCommonModes);
    // 获取当前的网络状态并回调
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0),^{
        SCNetworkReachabilityFlags flags;
        if (SCNetworkReachabilityGetFlags(self.networkReachability, &flags)) {
            AFPostReachabilityStatusChange(flags, callback);
        }
    });
}