AFNetWorking 3.0 學(xué)習(xí)記錄

AFNetWorking 的學(xué)習(xí)瓶蚂,主要以實(shí)際使用過(guò)程來(lái)看里面源碼具體做了什么事来颤。

AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];

 [manager POST:fullpath parameters:parameter success:successBlock failure:failureBlock]; 

從上面來(lái)看神僵,主要是三個(gè)過(guò)程:

  1. 初始化
  2. 發(fā)送請(qǐng)求
  3. 回調(diào)
    AFNetWorking 的大致結(jié)構(gòu),多個(gè)請(qǐng)求接口泽艘,最終走向一個(gè)獨(dú)立的session requset, 最后到統(tǒng)一的回調(diào)管理镐依。
Paste_Image.png

初始化


Paste_Image.png
  [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ā)起階段

Paste_Image.png
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)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末尿扯,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子焰雕,更是在濱河造成了極大的恐慌衷笋,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,820評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件矩屁,死亡現(xiàn)場(chǎng)離奇詭異辟宗,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)吝秕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,648評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門泊脐,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人烁峭,你說(shuō)我怎么就攤上這事容客。” “怎么了则剃?”我有些...
    開(kāi)封第一講書人閱讀 168,324評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵耘柱,是天一觀的道長(zhǎng)如捅。 經(jīng)常有香客問(wèn)我棍现,道長(zhǎng),這世上最難降的妖魔是什么镜遣? 我笑而不...
    開(kāi)封第一講書人閱讀 59,714評(píng)論 1 297
  • 正文 為了忘掉前任己肮,我火速辦了婚禮,結(jié)果婚禮上悲关,老公的妹妹穿的比我還像新娘谎僻。我一直安慰自己,他們只是感情好寓辱,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,724評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布艘绍。 她就那樣靜靜地躺著,像睡著了一般秫筏。 火紅的嫁衣襯著肌膚如雪诱鞠。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 52,328評(píng)論 1 310
  • 那天这敬,我揣著相機(jī)與錄音航夺,去河邊找鬼。 笑死崔涂,一個(gè)胖子當(dāng)著我的面吹牛阳掐,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 40,897評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼缭保,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼汛闸!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起涮俄,我...
    開(kāi)封第一講書人閱讀 39,804評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤蛉拙,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后彻亲,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體孕锄,經(jīng)...
    沈念sama閱讀 46,345評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,431評(píng)論 3 340
  • 正文 我和宋清朗相戀三年苞尝,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了畸肆。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,561評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡宙址,死狀恐怖轴脐,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情抡砂,我是刑警寧澤大咱,帶...
    沈念sama閱讀 36,238評(píng)論 5 350
  • 正文 年R本政府宣布,位于F島的核電站注益,受9級(jí)特大地震影響碴巾,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜丑搔,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,928評(píng)論 3 334
  • 文/蒙蒙 一厦瓢、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧啤月,春花似錦煮仇、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 32,417評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至郑诺,卻和暖如春夹姥,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背间景。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,528評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工佃声, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人倘要。 一個(gè)月前我還...
    沈念sama閱讀 48,983評(píng)論 3 376
  • 正文 我出身青樓圾亏,卻偏偏與公主長(zhǎng)得像十拣,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子志鹃,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,573評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容