AFNetworking是基于NSURLSession搭建的网络请求框架,发起请求流程如下:
1、AFHTTPSessionManager对象的requestSerializer生成NSMutableURLRequest对象
这一步为设置请求参数,我们的parameters参数为此步设置,若请求参数出现问题,我们可以在这一步中进行问题排查。
NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:method URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters error:&serializationError];
2、设置NSMutableURLRequest对象的headerField
for (NSString *headerField in headers.keyEnumerator) {
[request setValue:headers[headerField] forHTTPHeaderField:headerField];
}
4、AFHTTPSessionManager对象的NSURLSession属性生成NSURLSessionDataTask对象,NSURLSession回调代理为AFHTTPSessionManager对象
- (NSURLSession *)session {
@synchronized (self) {
if (!_session) {
_session = [NSURLSession sessionWithConfiguration:self.sessionConfiguration delegate:self delegateQueue:self.operationQueue];
}
}
return _session;
}
NSURLSessionDataTask *dataTask = [self.session dataTaskWithRequest:request];
5、创建AFURLSessionManagerTaskDelegate对象,设置回调代理和回调block,以NSURLSessionDataTask.taskIdentifier为key,delegate为value保存在mutableTaskDelegatesKeyedByTaskIdentifier字典中
AFURLSessionManagerTaskDelegate *delegate = [[AFURLSessionManagerTaskDelegate alloc] initWithTask:dataTask];
delegate.manager = self;
delegate.completionHandler = completionHandler;
dataTask.taskDescription = self.taskDescriptionForSessionTasks;
[self setDelegate:delegate forTask:dataTask];
delegate.uploadProgressBlock = uploadProgressBlock;
delegate.downloadProgressBlock = downloadProgressBlock;
- (void)setDelegate:(AFURLSessionManagerTaskDelegate *)delegate
forTask:(NSURLSessionTask *)task
{
NSParameterAssert(task);
NSParameterAssert(delegate);
[self.lock lock];
self.mutableTaskDelegatesKeyedByTaskIdentifier[@(task.taskIdentifier)] = delegate;
[self addNotificationObserverForTask:task];
[self.lock unlock];
}
6、AFHTTPSessionManager接收NSURLSession回调
AFHTTPSessionManager对象会从mutableTaskDelegatesKeyedByTaskIdentifier字典中根据NSURLSessionDataTask.taskIdentifier为key,取出代理delegate,进行数据拼接,进度回调调用等。
若接收数据或发送数据出现问题,则可以从这些代理中进行问题排查。
- (void)URLSession:(NSURLSession *)session
dataTask:(NSURLSessionDataTask *)dataTask
didReceiveData:(NSData *)data
{
AFURLSessionManagerTaskDelegate *delegate = [self delegateForTask:dataTask];
[delegate URLSession:session dataTask:dataTask didReceiveData:data];
if (self.dataTaskDidReceiveData) {
self.dataTaskDidReceiveData(session, dataTask, data);
}
}
- (void)URLSession:(__unused NSURLSession *)session
dataTask:(__unused NSURLSessionDataTask *)dataTask
didReceiveData:(NSData *)data
{
self.downloadProgress.totalUnitCount = dataTask.countOfBytesExpectedToReceive;
self.downloadProgress.completedUnitCount = dataTask.countOfBytesReceived;
[self.mutableData appendData:data];
}
7、数据接收完毕,调用AFHTTPSessionManager对象的responseSerializer的方法解析接收到的数据
若解析数据出现问题,我们可以在这一步里进行问题排查。
responseObject = [manager.responseSerializer responseObjectForResponse:task.response data:data error:&serializationError];
8、把解析的数据通过completionHandler block回调给使用者
if (self.completionHandler) {
self.completionHandler(task.response, responseObject, serializationError);
}
9、从mutableTaskDelegatesKeyedByTaskIdentifier移除NSURLSessionDataTask.taskIdentifier为key的对象信息
[self removeDelegateForTask:task];
- (void)removeDelegateForTask:(NSURLSessionTask *)task {
NSParameterAssert(task);
[self.lock lock];
[self removeNotificationObserverForTask:task];
[self.mutableTaskDelegatesKeyedByTaskIdentifier removeObjectForKey:@(task.taskIdentifier)];
[self.lock unlock];
}
在此过程中,我们发现AFHTTPSessionManager、AFURLSessionManager、AFURLSessionManagerTaskDelegate、AFHTTPRequestSerializer、AFHTTPResponseSerializer五个类极为重要,AFHTTPSessionManager、AFURLSessionManager为管理整个流程的类,AFURLSessionManagerTaskDelegate为保存回调的类,AFHTTPRequestSerializer为对请求头进行数据组装的类,AFHTTPResponseSerializer为接收数据后进行解析的类。
其中还有一个AFSecurityPolicy类,设置安全政策的管理类,https的ssl链接使用,可以设置三种不同的模式。
typedef NS_ENUM(NSUInteger, AFSSLPinningMode) {
AFSSLPinningModeNone, //Do not used pinned certificates to validate servers. 无条件信任返回的证书
AFSSLPinningModePublicKey, //Validate host certificates against public keys of pinned certificates. 与本地证书部分校验
AFSSLPinningModeCertificate, //Validate host certificates against pinned certificates. 与本地证书全部校验
};
网友评论