前言:URLSesstion实现网络请求的步骤
// step1. 初始化AFURLSessionManager对象 NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration]; AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration]; // step2. 获取AFURLSessionManager的task对象 NSURLSessionDataTask *dataTask = [manager dataTaskWithRequest:request completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) { if (error) { NSLog(@"Error: %@", error); } else { NSLog(@"Get Net data success!"); } }]; // step3. 发动task [dataTask resume];
下面可以看下AF如何实现这三个步骤的:
step1:实现生成Sesstion
核心属性
/** The managed session. */ @property (readonly, nonatomic, strong) NSURLSession *session; /** The operation queue on which delegate callbacks are run. */ @property (readonly, nonatomic, strong) NSOperationQueue *operationQueue; /** Responses sent from the server in data tasks created with `dataTaskWithRequest:success:failure:` and run using the `GET` / `POST` / et al. convenience methods are automatically validated and serialized by the response serializer. By default, this property is set to an instance of `AFJSONResponseSerializer`. @warning `responseSerializer` must not be `nil`. */ @property (nonatomic, strong) id <AFURLResponseSerialization> responseSerializer; ///------------------------------- /// @name Managing Security Policy ///------------------------------- /** The security policy used by created session to evaluate server trust for secure connections. `AFURLSessionManager` uses the `defaultPolicy` unless otherwise specified. */ @property (nonatomic, strong) AFSecurityPolicy *securityPolicy; #if !TARGET_OS_WATCH ///-------------------------------------- /// @name Monitoring Network Reachability ///-------------------------------------- /** The network reachability manager. `AFURLSessionManager` uses the `sharedManager` by default. */ @property (readwrite, nonatomic, strong) AFNetworkReachabilityManager *reachabilityManager; #endif ///---------------------------- /// @name Getting Session Tasks ///---------------------------- /** The data, upload, and download tasks currently run by the managed session. */ @property (readonly, nonatomic, strong) NSArray <NSURLSessionTask *> *tasks; /** The data tasks currently run by the managed session. */ @property (readonly, nonatomic, strong) NSArray <NSURLSessionDataTask *> *dataTasks; /** The upload tasks currently run by the managed session. */ @property (readonly, nonatomic, strong) NSArray <NSURLSessionUploadTask *> *uploadTasks; /** The download tasks currently run by the managed session. */ @property (readonly, nonatomic, strong) NSArray <NSURLSessionDownloadTask *> *downloadTasks; ///------------------------------- /// @name Managing Callback Queues ///------------------------------- /** The dispatch queue for `completionBlock`. If `NULL` (default), the main queue is used. */ @property (nonatomic, strong, nullable) dispatch_queue_t completionQueue; /** The dispatch group for `completionBlock`. If `NULL` (default), a private dispatch group is used. */ @property (nonatomic, strong, nullable) dispatch_group_t completionGroup;
核心方法解析
initWithSesstionConfiguration
(instancetype)initWithSessionConfiguration:(NSURLSessionConfiguration *)configuration { self = [super init]; if (!self) { return nil; } // =============== 设置NSURLSession =============== // 若configuration为nil,则采用默认defaultSessionConfiguration if (!configuration) { configuration = [NSURLSessionConfiguration defaultSessionConfiguration]; } self.sessionConfiguration = configuration; // session 的delegate callback queue, 最大并发为1 self.operationQueue = [[NSOperationQueue alloc] init]; self.operationQueue.maxConcurrentOperationCount = 1; // 初始化所管理的session self.session = [NSURLSession sessionWithConfiguration:self.sessionConfiguration delegate:self delegateQueue:self.operationQueue]; // =============== 设置response 数据序列化 =============== self.responseSerializer = [AFJSONResponseSerializer serializer]; // =============== 设置网络安全策略 =============== self.securityPolicy = [AFSecurityPolicy defaultPolicy]; // =============== 设置网络状态监控Manager(注意这里是一个全局单例实现) =============== #if !TARGET_OS_WATCH self.reachabilityManager = [AFNetworkReachabilityManager sharedManager]; #endif // =============== 设置存储NSURL task与AFURLSessionManagerTaskDelegate的词典(重点,在AFNet中,每一个task都会被匹配一个AFURLSessionManagerTaskDelegate 来做task的delegate事件处理) =============== self.mutableTaskDelegatesKeyedByTaskIdentifier = [[NSMutableDictionary alloc] init]; // =============== 设置AFURLSessionManagerTaskDelegate 词典的锁,确保词典在多线程访问时的线程安全=============== self.lock = [[NSLock alloc] init]; self.lock.name = AFURLSessionManagerLockName; // =============== 为所管理的session的所有task设置完成块(这里不是很明白,既然是初始化函数,那么应该没有任何task在运行才是,怎么需要在这里设置完成块呢???)=============== [self.session getTasksWithCompletionHandler:^(NSArray *dataTasks, NSArray *uploadTasks, NSArray *downloadTasks) { for (NSURLSessionDataTask *task in dataTasks) { [self addDelegateForDataTask:task uploadProgress:nil downloadProgress:nil completionHandler:nil]; } for (NSURLSessionUploadTask *uploadTask in uploadTasks) { [self addDelegateForUploadTask:uploadTask progress:nil completionHandler:nil]; } for (NSURLSessionDownloadTask *downloadTask in downloadTasks) { [self addDelegateForDownloadTask:downloadTask progress:nil destination:nil completionHandler:nil]; } }]; // =============== 返回初始化好的self =============== return self; }
总结:1.初始化sesstion,opretion,安全策略,网络可达性,序列化/反序列化,data数组,downLoadData数组,upLoadData数组
2.进入了sesstion的sesstionWithConfiguration的方法里面,传入delegate
Setp2:生成Task
- (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 { __block NSURLSessionDataTask *dataTask = nil; url_session_manager_create_task_safely(^{ dataTask = [self.session dataTaskWithRequest:request]; }); [self addDelegateForDataTask:dataTask uploadProgress:uploadProgressBlock downloadProgress:downloadProgressBlock completionHandler:completionHandler]; return dataTask; }
总结:1.dataTaskWithRequest建立task
2.addDelegatForDataTask建立每一个delegate管理每个task
- (void)addDelegateForDataTask:(NSURLSessionDataTask *)dataTask uploadProgress:(nullable void (^)(NSProgress *uploadProgress)) uploadProgressBlock downloadProgress:(nullable void (^)(NSProgress *downloadProgress)) downloadProgressBlock completionHandler:(void (^)(NSURLResponse *response, id responseObject, NSError *error))completionHandler {
// 创建AFURLSessionManagerTaskDelegate对象 AFURLSessionManagerTaskDelegate *delegate = [[AFURLSessionManagerTaskDelegate alloc] init]; // 设置AF delegate的完成块为用户传入的完成块 delegate.completionHandler = completionHandler; // 设置dataTask的taskDescription dataTask.taskDescription = self.taskDescriptionForSessionTasks; // 设置AF delegate的上传进度,下载进度块。 delegate.uploadProgressBlock = uploadProgressBlock; delegate.downloadProgressBlock = downloadProgressBlock; // AFURLSessionManagerTaskDelegate与AFURLSessionManager建立相互关系 delegate.manager = self; // ***** 将AF delegate对象与 dataTask建立关系 [self setDelegate:delegate forTask:dataTask]; }
- (void)setDelegate:(AFURLSessionManagerTaskDelegate *)delegate forTask:(NSURLSessionTask *)task { NSParameterAssert(task); NSParameterAssert(delegate); // 加锁,确保词典的线程安全 [self.lock lock]; // 将AF delegate放入以taskIdentifier标记的词典中(同一个NSURLSession中的taskIdentifier是唯一的) self.mutableTaskDelegatesKeyedByTaskIdentifier[@(task.taskIdentifier)] = delegate; // 为AF delegate 设置task 的progress监听 [delegate setupProgressForTask:task]; [self addNotificationObserverForTask:task]; // 词典操作完毕,解锁 [self.lock unlock]; }
总结:1.初始化dataDlegate 2.建立block对应delegate的关系 3.建立task和delegate的对应关系
Setp3.delegate之间的传递
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error { // step1. 应交由AF task delegate处理的事件,取出对应AF task delegate, AFURLSessionManagerTaskDelegate *delegate = [self delegateForTask:task]; // delegate may be nil when completing a task in the background if (delegate) { // step2. 将事件交由AF task delegate处理 [delegate URLSession:session task:task didCompleteWithError:error]; // NOTE: 此处是session task最终的回调函数,task不会再返回任何信息。因此删除对应的AF task delegate [self removeDelegateForTask:task]; } // step3. 若有对应的user block,则调用之 if (self.taskDidComplete) { self.taskDidComplete(session, task, error); } }
1.获取对应task的delegate,delegateForTask
2.调用AF的delegate的对应的complete方法,传给了AFD
3.判断,如果有block,设置block回调
AFNetworkingSesstionDelegate
@interface AFURLSessionManagerTaskDelegate : NSObject <NSURLSessionTaskDelegate, NSURLSessionDataDelegate, NSURLSessionDownloadDelegate> @property (nonatomic, weak) AFURLSessionManager *manager; @property (nonatomic, strong) NSMutableData *mutableData; // 保存服务器返回的数据 @property (nonatomic, strong) NSProgress *uploadProgress; // 上传进度 @property (nonatomic, strong) NSProgress *downloadProgress; // 下载进度 @property (nonatomic, copy) NSURL *downloadFileURL; // 下载文件目的存储地址 @property (nonatomic, copy) AFURLSessionDownloadTaskDidFinishDownloadingBlock downloadTaskDidFinishDownloading; @property (nonatomic, copy) AFURLSessionTaskProgressBlock uploadProgressBlock; @property (nonatomic, copy) AFURLSessionTaskProgressBlock downloadProgressBlock; @property (nonatomic, copy) AFURLSessionTaskCompletionHandler completionHandler; @end
编者寄语,AFM对sesstionManager的封装,首先是基于实现几个步骤:1.初始化sesstionManager 2.初始化Task 3.回调的传递。
AFM在InitConfigution里面初始化了sesstion和相关的其它属性,完成了第一个问题。
AFM在dataTask方法里面初始化了 sesstion的dataTask,并且为每个dataTask分配了一个delegate
AFM在setdelegate里面将sesstion的回调传递给AF,如果有回调,使用delegatForTask方法,获取AF的delegate,如果有Block,赋值给Block
为什么不在Managter方法里面直接设置delelgate获取Bblock呢,而使用了中间层的AFD