AFNetWorking 的學(xué)習(xí)瓶蚂,主要以實(shí)際使用過(guò)程來(lái)看里面源碼具體做了什么事来颤。
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
[manager POST:fullpath parameters:parameter success:successBlock failure:failureBlock];
從上面來(lái)看神僵,主要是三個(gè)過(guò)程:
- 初始化
- 發(fā)送請(qǐng)求
- 回調(diào)
AFNetWorking 的大致結(jié)構(gòu),多個(gè)請(qǐng)求接口泽艘,最終走向一個(gè)獨(dú)立的session requset, 最后到統(tǒng)一的回調(diào)管理镐依。
初始化
[AFHTTPSessionManager manager];
AFHTTPSessionManager.h
- (instancetype)initWithBaseURL:(NSURL *)url
sessionConfiguration:(NSURLSessionConfiguration *)configuration
{
self = [super initWithSessionConfiguration:configuration];
if (!self) {
return nil;
}
// Ensure terminal slash for baseURL path, so that NSURL +URLWithString:relativeToURL: works as expected
if ([[url path] length] > 0 && ![[url absoluteString] hasSuffix:@"/"]) {
url = [url URLByAppendingPathComponent:@""];
}
self.baseURL = url;
self.requestSerializer = [AFHTTPRequestSerializer serializer];
self.responseSerializer = [AFJSONResponseSerializer serializer];
return self;
}
在AFHTTPSessionManager.h中匹涮,manager 做的工作就是
1、 創(chuàng)建Session (具體細(xì)節(jié)要AFURLSessionManager.h)
2 槐壳、初始化baseURL
3然低、 request Serializer
4、 response Serializer
創(chuàng)建Session的時(shí)候做了些什么呢务唐?
AFURLSessionManager.h
- (instancetype)initWithSessionConfiguration:(NSURLSessionConfiguration *)configuration {
self = [super init];
if (!self) {
return nil;
}
if (!configuration) {
configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
}
self.sessionConfiguration = configuration;
self.operationQueue = [[NSOperationQueue alloc] init];
self.operationQueue.maxConcurrentOperationCount = 1;
self.session = [NSURLSession sessionWithConfiguration:self.sessionConfiguration delegate:self delegateQueue:self.operationQueue];
self.responseSerializer = [AFJSONResponseSerializer serializer];
self.securityPolicy = [AFSecurityPolicy defaultPolicy];
#if !TARGET_OS_WATCH
self.reachabilityManager = [AFNetworkReachabilityManager sharedManager];
#endif
self.mutableTaskDelegatesKeyedByTaskIdentifier = [[NSMutableDictionary alloc] init];
self.lock = [[NSLock alloc] init];
self.lock.name = AFURLSessionManagerLockName;
[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];
}
}];
return self;
}
AFURLSession初始化了:
1雳攘、初始化 sessionConfiguration
2、operationQueue
3枫笛、初始化 session
4吨灭、初始化 responseSerializer
5、初始化了securityPolicy
6刑巧、初始化了reachabilityManager
7喧兄、初始 化mutableTaskDelegatesKeyedByTaskIdentifier
解析:
前三步,初始化的是session啊楚,并且session運(yùn)行在一個(gè)私有的隊(duì)列里面群扶。那么就是說(shuō),所有的task都會(huì)運(yùn)行在一個(gè)私有的隊(duì)列里面爷狈。也就是AFNetworking的網(wǎng)絡(luò)請(qǐng)求都是異步的辰企,不會(huì)阻塞主線程。
從上面的初始化過(guò)程來(lái)看蚯斯,AFHTTPSessionManager.h 薄风,用manager饵较,創(chuàng)建了一個(gè)session,(*這個(gè)是一個(gè)單例遭赂,也就是說(shuō)只會(huì)創(chuàng)建一次session循诉,以后的每次請(qǐng)求都不會(huì)重復(fù)創(chuàng)建HTTP連接,session用了http2.0的新特性撇他,包括 http1.0 keepalive)
post 調(diào)用過(guò)程
![Uploading Paste_Image_247951.png . . .]
[manager POST:fullpath parameters:parameter success:successBlock failure:failureBlock];
POST 分為兩個(gè)階段:
1茄猫、AFHTTPSessionManager.h 參數(shù)解析階段
2、AFURLSessionManager.h task發(fā)起階段
AFHTTPSessionManager.h 階段
POST 請(qǐng)求 ---> dataTask
- (NSURLSessionDataTask *)POST:(NSString *)URLString
parameters:(id)parameters
progress:(void (^)(NSProgress * _Nonnull))uploadProgress
success:(void (^)(NSURLSessionDataTask * _Nonnull, id _Nullable))success
failure:(void (^)(NSURLSessionDataTask * _Nullable, NSError * _Nonnull))failure
{
NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"POST" URLString:URLString parameters:parameters uploadProgress:uploadProgress downloadProgress:nil success:success failure:failure];
[dataTask resume];
return dataTask;
}
- (NSURLSessionDataTask *)dataTaskWithHTTPMethod:(NSString *)method
URLString:(NSString *)URLString
parameters:(id)parameters
uploadProgress:(nullable void (^)(NSProgress *uploadProgress)) uploadProgress
downloadProgress:(nullable void (^)(NSProgress *downloadProgress)) downloadProgress
success:(void (^)(NSURLSessionDataTask *, id))success
failure:(void (^)(NSURLSessionDataTask *, NSError *))failure
{
NSError *serializationError = nil;
NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:method URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters error:&serializationError];
if (serializationError) {
if (failure) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wgnu"
dispatch_async(self.completionQueue ?: dispatch_get_main_queue(), ^{
failure(nil, serializationError);
});
#pragma clang diagnostic pop
}
return nil;
}
__block NSURLSessionDataTask *dataTask = nil;
dataTask = [self dataTaskWithRequest:request
uploadProgress:uploadProgress
downloadProgress:downloadProgress
completionHandler:^(NSURLResponse * __unused response, id responseObject, NSError *error) {
if (error) {
if (failure) {
failure(dataTask, error);
}
} else {
if (success) {
success(dataTask, responseObject);
}
}
}];
return dataTask;
}
1困肩、創(chuàng)建請(qǐng)求(主要由requestSerializer划纽,細(xì)節(jié)要看AFURLRequstSerialization.h)
2、 調(diào)用AFURLSessionManager.h dataTaskRequest
AFURLSessionManager.h 階段
- (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;
}
在AFURLSessionManager.h 里面主要是創(chuàng)建dataTask锌畸,并且把dataTask 創(chuàng)建一個(gè)AFURLSessionManagerTaskDelegate
- (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 *delegate = [[AFURLSessionManagerTaskDelegate alloc] init];
delegate.manager = self;
delegate.completionHandler = completionHandler;
dataTask.taskDescription = self.taskDescriptionForSessionTasks;
[self setDelegate:delegate forTask:dataTask];
delegate.uploadProgressBlock = uploadProgressBlock;
delegate.downloadProgressBlock = downloadProgressBlock;
}
那這個(gè)代理干什么的呢勇劣,有什么用呢?
Delegate AFURLSessionManagerTaskDelegate
看看這個(gè)代理的定義潭枣,這個(gè)代理實(shí)現(xiàn)了NSURLSessionTaskDelegate比默, NSURLSessionDataDelegate,
NSURLSessionDownloadDelegate的方法盆犁,那么session的回調(diào)就會(huì)在這里命咐。并且每一個(gè)代理,都記錄了每一個(gè)請(qǐng)求的回調(diào)谐岁,所以醋奠,在AFNetworking,請(qǐng)求的時(shí)候伊佃,才能從眾多的請(qǐng)求中钝域,確定調(diào)用那個(gè)一個(gè)請(qǐng)求的回調(diào)。
@interface AFURLSessionManagerTaskDelegate : NSObject <NSURLSessionTaskDelegate, NSURLSessionDataDelegate, NSURLSessionDownloadDelegate>
@property (nonatomic, copy) AFURLSessionTaskProgressBlock uploadProgressBlock;
@property (nonatomic, copy) AFURLSessionTaskProgressBlock downloadProgressBlock;
@property (nonatomic, copy) AFURLSessionTaskCompletionHandler completionHandler;
#pragma mark - NSURLSessionTaskDelegate
- (void)URLSession:(__unused NSURLSession *)session
task:(NSURLSessionTask *)task
didCompleteWithError:(NSError *)error
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wgnu"
__strong AFURLSessionManager *manager = self.manager;
__block id responseObject = nil;
__block NSMutableDictionary *userInfo = [NSMutableDictionary dictionary];
userInfo[AFNetworkingTaskDidCompleteResponseSerializerKey] = manager.responseSerializer;
//Performance Improvement from #2672
NSData *data = nil;
if (self.mutableData) {
data = [self.mutableData copy];
//We no longer need the reference, so nil it out to gain back some memory.
self.mutableData = nil;
}
if (self.downloadFileURL) {
userInfo[AFNetworkingTaskDidCompleteAssetPathKey] = self.downloadFileURL;
} else if (data) {
userInfo[AFNetworkingTaskDidCompleteResponseDataKey] = data;
}
if (error) {
userInfo[AFNetworkingTaskDidCompleteErrorKey] = error;
dispatch_group_async(manager.completionGroup ?: url_session_manager_completion_group(), manager.completionQueue ?: dispatch_get_main_queue(), ^{
if (self.completionHandler) {
self.completionHandler(task.response, responseObject, error);
}
dispatch_async(dispatch_get_main_queue(), ^{
[[NSNotificationCenter defaultCenter] postNotificationName:AFNetworkingTaskDidCompleteNotification object:task userInfo:userInfo];
});
});
} else {
dispatch_async(url_session_manager_processing_queue(), ^{
NSError *serializationError = nil;
responseObject = [manager.responseSerializer responseObjectForResponse:task.response data:data error:&serializationError];
if (self.downloadFileURL) {
responseObject = self.downloadFileURL;
}
if (responseObject) {
userInfo[AFNetworkingTaskDidCompleteSerializedResponseKey] = responseObject;
}
if (serializationError) {
userInfo[AFNetworkingTaskDidCompleteErrorKey] = serializationError;
}
dispatch_group_async(manager.completionGroup ?: url_session_manager_completion_group(), manager.completionQueue ?: dispatch_get_main_queue(), ^{
if (self.completionHandler) {
self.completionHandler(task.response, responseObject, serializationError);
}
dispatch_async(dispatch_get_main_queue(), ^{
[[NSNotificationCenter defaultCenter] postNotificationName:AFNetworkingTaskDidCompleteNotification object:task userInfo:userInfo];
});
});
});
}
#pragma clang diagnostic pop
}
一個(gè)網(wǎng)絡(luò)請(qǐng)求的過(guò)程大致分為幾個(gè)過(guò)程:
1锭魔、創(chuàng)建request
2例证、創(chuàng)建session
3、創(chuàng)建task 并且請(qǐng)求
4迷捧、回調(diào)
總結(jié)
AFNetWorking在每一個(gè)階段织咧,都做了很多的事:
1、初始化階段漠秋;AFNetWorking 的manager 會(huì)幫忙創(chuàng)建一個(gè)單例笙蒙,來(lái)管理session請(qǐng)求。
2庆锦、通過(guò) AFURLRequestSerializer 初始化request
3捅位、創(chuàng)建session task,添加到當(dāng)前的session允許的operation Queue里面,并且為每一個(gè)task創(chuàng)建AFURLSessionManagerTaskDelegate
4艇搀、通過(guò)AFURLRsponseSerializer 解析回調(diào)