AFNetworking 是一个强大的 iOS 和 macOS 网络库,它通过封装 NSURLSession 和其他底层网络库,提供了一个简洁且强大的 API 接口。以下是 AFNetworking 的主要工作原理和关键部分的详细分析:
核心组件
AFNetworking 主要由以下几个核心组件组成:
- AFHTTPSessionManager: 基于
NSURLSession的高级管理器,提供 HTTP 请求的便利方法。 - AFURLSessionManager: 低级别的会话管理器,管理
NSURLSession的生命周期和委托。 - AFNetworkReachabilityManager: 网络可达性检查工具,监测网络状态的变化。
- AFSecurityPolicy: 安全策略对象,处理 SSL 证书验证。
AFHTTPSessionManager 实现
AFHTTPSessionManager 是 AFNetworking 中最常用的类,继承自 AFURLSessionManager,并扩展了许多具体用于处理 HTTP 请求的便利方法。
@implementation AFHTTPSessionManager
- (instancetype)initWithBaseURL:(NSURL *)url sessionConfiguration:(NSURLSessionConfiguration *)configuration {
self = [super initWithSessionConfiguration:configuration];
if (!self) {
return nil;
}
self.baseURL = url;
self.requestSerializer = [AFHTTPRequestSerializer serializer];
self.responseSerializer = [AFJSONResponseSerializer serializer];
return self;
}
- (NSURLSessionDataTask *)GET:(NSString *)URLString
parameters:(id)parameters
headers:(NSDictionary <NSString *, NSString *> *)headers
progress:(void (^)(NSProgress *downloadProgress))downloadProgress
success:(void (^)(NSURLSessionDataTask *task, id responseObject))success
failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure
{
NSError *serializationError = nil;
NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:@"GET" 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;
}
for (NSString *field in headers) {
[request setValue:headers[field] forHTTPHeaderField:field];
}
NSURLSessionDataTask *dataTask = [self dataTaskWithRequest:request uploadProgress:nil downloadProgress:downloadProgress completionHandler:^(NSURLResponse * __unused response, id responseObject, NSError *error) {
if (error) {
if (failure) {
failure(dataTask, error);
}
} else {
if (success) {
success(dataTask, responseObject);
}
}
}];
[dataTask resume];
return dataTask;
}
@end
请求和响应序列化
AFNetworking 提供了多种序列化器来处理请求参数和响应数据:
@implementation AFHTTPRequestSerializer
- (NSMutableURLRequest *)requestWithMethod:(NSString *)method
URLString:(NSString *)URLString
parameters:(id)parameters
error:(NSError *__autoreleasing *)error
{
NSParameterAssert(method);
NSParameterAssert(URLString);
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:URLString]];
request.HTTPMethod = method;
if (parameters) {
if ([method isEqualToString:@"GET"] || [method isEqualToString:@"HEAD"] || [method isEqualToString:@"DELETE"]) {
NSString *query = AFQueryStringFromParameters(parameters);
if (query && query.length > 0) {
URLString = [URLString stringByAppendingFormat:[URLString rangeOfString:@"?"].location == NSNotFound ? @"?%@" : @"&%@", query];
request.URL = [NSURL URLWithString:URLString];
}
} else {
request.HTTPBody = [NSJSONSerialization dataWithJSONObject:parameters options:0 error:error];
}
}
return request;
}
@end
会话管理
AFURLSessionManager 是对 NSURLSession 的封装,管理会话及其任务的生命周期:
@implementation AFURLSessionManager
- (instancetype)initWithSessionConfiguration:(NSURLSessionConfiguration *)configuration {
self = [super init];
if (!self) {
return nil;
}
self.sessionConfiguration = configuration;
self.session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil];
self.operationQueue = [[NSOperationQueue alloc] init];
self.operationQueue.maxConcurrentOperationCount = 1;
return self;
}
- (NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)request
uploadProgress:(void (^)(NSProgress *uploadProgress))uploadProgressBlock
downloadProgress:(void (^)(NSProgress *downloadProgress))downloadProgressBlock
completionHandler:(void (^)(NSURLResponse *response, id responseObject, NSError *error))completionHandler
{
NSURLSessionDataTask *dataTask = [self.session dataTaskWithRequest:request];
[self setDelegateForTask:dataTask uploadProgress:uploadProgressBlock downloadProgress:downloadProgressBlock completionHandler:completionHandler];
return dataTask;
}
- (void)setDelegateForTask:(NSURLSessionTask *)task
uploadProgress:(void (^)(NSProgress *uploadProgress))uploadProgressBlock
downloadProgress:(void (^)(NSProgress *downloadProgress))downloadProgressBlock
completionHandler:(void (^)(NSURLResponse *response, id responseObject, NSError *error))completionHandler
{
AFURLSessionManagerTaskDelegate *delegate = [[AFURLSessionManagerTaskDelegate alloc] init];
delegate.manager = self;
delegate.completionHandler = completionHandler;
delegate.uploadProgressBlock = uploadProgressBlock;
delegate.downloadProgressBlock = downloadProgressBlock;
self.mutableTaskDelegatesKeyedByTaskIdentifier[@(task.taskIdentifier)] = delegate;
[task addObserver:self forKeyPath:NSStringFromSelector(@selector(state)) options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:AFTaskStateChangedContext];
}
@end
网络可达性
AFNetworkReachabilityManager 利用 SCNetworkReachability 监控网络状态变化:
@implementation AFNetworkReachabilityManager
+ (instancetype)sharedManager {
static AFNetworkReachabilityManager *_sharedManager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_sharedManager = [self manager];
});
return _sharedManager;
}
- (void)startMonitoring {
SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithName(NULL, [self.baseURL.host UTF8String]);
self.networkReachability = reachability;
SCNetworkReachabilityContext context = {0, (__bridge void *)(self), NULL, NULL, NULL};
SCNetworkReachabilitySetCallback(reachability, AFNetworkReachabilityCallback, &context);
SCNetworkReachabilityScheduleWithRunLoop(reachability, CFRunLoopGetMain(), kCFRunLoopCommonModes);
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
SCNetworkReachabilityFlags flags;
if (SCNetworkReachabilityGetFlags(reachability, &flags)) {
AFPostReachabilityStatusChange(flags);
}
});
}
@end
static void AFNetworkReachabilityCallback(SCNetworkReachabilityRef __unused target, SCNetworkReachabilityFlags flags, void *info) {
AFNetworkReachabilityStatus status = AFNetworkReachabilityStatusForFlags(flags);
dispatch_async(dispatch_get_main_queue(), ^{
[[NSNotificationCenter defaultCenter] postNotificationName:AFNetworkingReachabilityDidChangeNotification object:nil userInfo:@{ AFNetworkingReachabilityNotificationStatusItem: @(status) }];
});
}
安全策略
AFSecurityPolicy 用于 SSL 证书验证:
@implementation AFSecurityPolicy
+ (instancetype)policyWithPinningMode:(AFSSLPinningMode)pinningMode {
AFSecurityPolicy *securityPolicy = [[self alloc] init];
securityPolicy.SSLPinningMode = pinningMode;
return securityPolicy;
}
- (BOOL)evaluateServerTrust:(SecTrustRef)serverTrust forDomain:(NSString *)domain {
switch (self.SSLPinningMode) {
case AFSSLPinningModeNone:
return YES;
case AFSSLPinningModePublicKey:
case AFSSLPinningModeCertificate:
return [self.pinnedCertificates containsObject:(__bridge id)(serverTrust)];
default:
return NO;
}
}
@end
异步处理
AFNetworking 使用 GCD 来管理并发队列:
dispatch_async(self.completionQueue ?: dispatch_get_main_queue(), ^{
if (success) {
success(task, responseObject);
}
});
总结来说,AFNetworking 通过封装 NSURLSession 提供了简洁且强大的 API 接口,结合请求序列化、响应序列化、网络可达性和 SSL 安全策略等模块化设计,使得网络请求和响应处理更加简便和灵活。