[关闭]
@CoDancer 2018-04-30T12:56:24.000000Z 字数 7154 阅读 899

AFNetworking 底部代码的阅读笔记

网络 数据请求


先从AFNetworking框架从上往下看,可以看到它的对外接口主要有:

  1. - (NSURLSessionDataTask *)GET:(NSString *)URLString
  2. parameters:(id)parameters
  3. progress:(void (^)(NSProgress * _Nonnull))downloadProgress
  4. success:(void (^)(NSURLSessionDataTask * _Nonnull, id _Nullable))success
  5. failure:(void (^)(NSURLSessionDataTask * _Nullable, NSError * _Nonnull))failure
当然这是通过AFHTTPSessionManager的对象去调用,返回的是NSURLSessionDataTask,在这个方法中,我们需要关心的有两个地方,一个是block事件的数据返回,一个是return返回的NSURLSessionDataTask的对象。

再往下面看一层是:
  1. - (NSURLSessionDataTask *)dataTaskWithHTTPMethod:(NSString *)method
  2. URLString:(NSString *)URLString
  3. parameters:(id)parameters
  4. uploadProgress:(nullable void (^)(NSProgress *uploadProgress)) uploadProgress
  5. downloadProgress:(nullable void (^)(NSProgress *downloadProgress)) downloadProgress
  6. success:(void (^)(NSURLSessionDataTask *, id))success
  7. failure:(void (^)(NSURLSessionDataTask *, NSError *))failure

在这个方法中有:

  1. NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:method URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters error:&serializationError];

创建可改变的网络请求,在这个请求中设置

  1. NSMutableURLRequest *mutableRequest = [[NSMutableURLRequest alloc] initWithURL:url];
  2. mutableRequest.HTTPMethod = method;

并且设置请求对象中头部字段HTTPHeaderField

  1. [self setValue:[acceptLanguagesComponents componentsJoinedByString:@", "] forHTTPHeaderField:@"Accept-Language"];
  2. NSString *userAgent = nil;
  3. #if TARGET_OS_IOS
  4. // User-Agent Header; see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.43
  5. userAgent = [NSString stringWithFormat:@"%@/%@ (%@; iOS %@; Scale/%0.2f)", [[NSBundle mainBundle] infoDictionary][(__bridge NSString *)kCFBundleExecutableKey] ?: [[NSBundle mainBundle] infoDictionary][(__bridge NSString *)kCFBundleIdentifierKey], [[NSBundle mainBundle] infoDictionary][@"CFBundleShortVersionString"] ?: [[NSBundle mainBundle] infoDictionary][(__bridge NSString *)kCFBundleVersionKey], [[UIDevice currentDevice] model], [[UIDevice currentDevice] systemVersion], [[UIScreen mainScreen] scale]];
  1. >_mutableHTTPRequestHeaders:
  2. {
  3. "Accept-Language" = "en;q=1";
  4. "User-Agent" = "iOS Example/1.0 (iPhone; iOS 11.2; Scale/2.00)";
  5. }

初始化好网络请求对象后,然后把它当作参数传到方法中。

  1. - (NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)request
  2. uploadProgress:(nullable void (^)(NSProgress *uploadProgress)) uploadProgressBlock
  3. downloadProgress:(nullable void (^)(NSProgress *downloadProgress)) downloadProgressBlock
  4. completionHandler:(nullable void (^)(NSURLResponse *response, id _Nullable responseObject, NSError * _Nullable error))completionHandler {
  5. __block NSURLSessionDataTask *dataTask = nil;
  6. url_session_manager_create_task_safely(^{
  7. dataTask = [self.session dataTaskWithRequest:request];
  8. });
  9. [self addDelegateForDataTask:dataTask uploadProgress:uploadProgressBlock downloadProgress:downloadProgressBlock completionHandler:completionHandler];
  10. return dataTask;
  11. }

当然这个方法中返回的还是NSURLSessionDataTask的对象,但我们需要看的是block中的处理。
在这个方法中主要有两个通知

  1. - (void)addNotificationObserverForTask:(NSURLSessionTask *)task {
  2. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(taskDidResume:) name:AFNSURLSessionTaskDidResumeNotification object:task];
  3. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(taskDidSuspend:) name:AFNSURLSessionTaskDidSuspendNotification object:task];
  4. }

监听恢复网络连接和暂停的事件。
而在创建AFHTTPSessionManager对象是的方法中有:

  1. - (instancetype)initWithSessionConfiguration:(NSURLSessionConfiguration *)configuration

这里面主要有

  1. self.session = [NSURLSession sessionWithConfiguration:self.sessionConfiguration delegate:self delegateQueue:self.operationQueue];
  2. [self.session getTasksWithCompletionHandler:^(NSArray *dataTasks, NSArray *uploadTasks, NSArray *downloadTasks) {
  3. for (NSURLSessionDataTask *task in dataTasks) {
  4. [self addDelegateForDataTask:task uploadProgress:nil downloadProgress:nil completionHandler:nil];
  5. }
  6. for (NSURLSessionUploadTask *uploadTask in uploadTasks) {
  7. [self addDelegateForUploadTask:uploadTask progress:nil completionHandler:nil];
  8. }
  9. for (NSURLSessionDownloadTask *downloadTask in downloadTasks) {
  10. [self addDelegateForDownloadTask:downloadTask progress:nil destination:nil completionHandler:nil];
  11. }
  12. }];

当然我们终于快看到了数据交接的底部了,就是AFURLSessionManager对象实现了 协议中的方法,而在实现这些方法中(举一个例子说明)

  1. - (void)URLSession:(NSURLSession *)session
  2. task:(NSURLSessionTask *)task
  3. didCompleteWithError:(NSError *)error
  4. {
  5. AFURLSessionManagerTaskDelegate *delegate = [self delegateForTask:task];
  6. // delegate may be nil when completing a task in the background
  7. if (delegate) {
  8. [delegate URLSession:session task:task didCompleteWithError:error];
  9. [self removeDelegateForTask:task];
  10. }
  11. if (self.taskDidComplete) {
  12. self.taskDidComplete(session, task, error);
  13. }
  14. }

这个时候创建了一个AFURLSessionManagerTaskDelegate的对象,当然这个对象也实现了那些代理,而在这个类中,与原生IOS交接的方法中

  1. - (void)URLSession:(__unused NSURLSession *)session
  2. task:(NSURLSessionTask *)task
  3. didCompleteWithError:(NSError *)error
  4. dispatch_async(url_session_manager_processing_queue(), ^{
  5. NSError *serializationError = nil;
  6. responseObject = [manager.responseSerializer responseObjectForResponse:task.response data:data error:&serializationError];
  7. if (self.downloadFileURL) {
  8. responseObject = self.downloadFileURL;
  9. }
  10. if (responseObject) {
  11. userInfo[AFNetworkingTaskDidCompleteSerializedResponseKey] = responseObject;
  12. }
  13. if (serializationError) {
  14. userInfo[AFNetworkingTaskDidCompleteErrorKey] = serializationError;
  15. }
  16. dispatch_group_async(manager.completionGroup ?: url_session_manager_completion_group(), manager.completionQueue ?: dispatch_get_main_queue(), ^{
  17. if (self.completionHandler) {
  18. self.completionHandler(task.response, responseObject, serializationError);
  19. }
  20. dispatch_async(dispatch_get_main_queue(), ^{
  21. [[NSNotificationCenter defaultCenter] postNotificationName:AFNetworkingTaskDidCompleteNotification object:task userInfo:userInfo];
  22. });
  23. });
  24. });

这里我们看到dispatch_group_async

而它的作用是:可以实现监听一组任务是否完成,完成后得到通知执行其他的操作。

void dispatch_group_async(dispatch_group_t group,
                      dispatch_queue_t queue,
                      dispatch_block_t block);

group: 对应的任务组
queue: block任务执行的线程队列

在AFURLSessionManager对象中完成了队列后,就会获取主线程并把需要的数据通过回调传出去,当然也会通知这个任务完成的通知。

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(networkRequestDidFinish:) name:AFNetworkingTaskDidCompleteNotification object:nil];
  1. - (void)networkRequestDidFinish:(NSNotification *)notification {
  2. if ([AFNetworkRequestFromNotification(notification) URL]) {
  3. [self decrementActivityCount];
  4. }
  5. }

这样就完成了数据的获取和回调。

NSURLSessionDataTaskAFHTTPSessionManagerAFURLSessionManagerAFURLSessionManagerTaskDelegatecompletionHandlerAFHTTPSessionManager
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注