Blog: Dravenesshtml
關注倉庫,及時得到更新:iOS-Source-Code-Analyzegit
在這一系列的文章中,我會對 AFNetworking 的源代碼進行分析,深刻了解一下它是如何構建的,如何在平常中完成發送 HTTP 請求、構建網絡層這一任務。github
AFNetworking 是現在 iOS 開發中不可缺乏的組件之一。它的 github 配置上是以下介紹的:json
Perhaps the most important feature of all, however, is the amazing community of developers who use and contribute to AFNetworking every day. AFNetworking powers some of the most popular and critically-acclaimed apps on the iPhone, iPad, and Mac.安全
能夠說使用 AFNetworking 的工程師構成的社區才使得它變得很是重要。服務器
咱們今天是來深刻研究一下這個與咱們平常開發密切相關的框架是如何實現的。網絡
這是我對 AFNetworking 整個架構的理解,隨後一系列的文章也會逐步分析這些模塊。session
在這篇文章中,咱們有兩個問題須要瞭解:架構
如何使用 NSURLSession 發出 HTTP 請求app
如何使用 AFNetworking 發出 HTTP 請求
NSURLSession
以及與它相關的類爲咱們提供了下載內容的 API,這個 API 提供了一系列的代理方法來支持身份認證,而且支持後臺下載。
使用 NSURLSession
來進行 HTTP 請求而且得到數據總共有五個步驟:
實例化一個 NSURLRequest/NSMutableURLRequest
,設置 URL
經過 - sharedSession
方法獲取 NSURLSession
在 session 上調用 - dataTaskWithRequest:completionHandler:
方法返回一個 NSURLSessionDataTask
向 data task 發送消息 - resume
,開始執行這個任務
在 completionHandler 中將數據編碼,返回字符串
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[[NSURL alloc] initWithString:@"https://github.com"]]; NSURLSession *session = [NSURLSession sharedSession]; NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { NSString *dataStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; NSLog(@"%@", dataStr); }]; [task resume];
這一段代碼能夠說是使用 NSURLSession
發送請求最簡單的一段代碼了,當你運行這段代碼會在控制檯看到一坨 github 首頁的 html。
<!DOCTYPE html> <html lang="en" class=""> <head prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb# object: http://ogp.me/ns/object# article: http://ogp.me/ns/article# profile: http://ogp.me/ns/profile#"> <meta charset='utf-8'> ... </head> ... </html>
AFNetworking 的使用也是比較簡單的,使用它來發出 HTTP 請求有兩個步驟
以服務器的主機地址或者域名生成一個 AFHTTPSessionManager 的實例
調用 - GET:parameters:progress:success:failure:
方法
AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc] initWithBaseURL:[[NSURL alloc] initWithString:@"hostname"]]; [manager GET:@"relative_url" parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { NSLog(@"%@" ,responseObject); } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { NSLog(@"%@", error); }];
注意:在 iOS9 中,蘋果默認全局 HTTPs,若是你要發送不安全的 HTTP 請求,須要在 info.plist 中加入以下鍵值對才能發出不安全的 HTTP 請求
還有一件事情是要注意的是,AFNetworking 默認接收 json 格式的響應(由於這是在 iOS 平臺上的框架,通常不須要 text/html),若是想要返回 html,須要設置
acceptableContentTypes
在這一節中咱們要分析一下在上面兩個方法的調用棧,首先來看的是 AFHTTPSessionManager
的初始化方法 - initWithBaseURL:
- [AFHTTPSessionManager initWithBaseURL:] - [AFHTTPSessionManager initWithBaseURL:sessionConfiguration:] - [AFURLSessionManager initWithSessionConfiguration:] - [NSURLSession sessionWithConfiguration:delegate:delegateQueue:] - [AFJSONResponseSerializer serializer] // 負責序列化響應 - [AFSecurityPolicy defaultPolicy] // 負責身份認證 - [AFNetworkReachabilityManager sharedManager] // 查看網絡鏈接狀況 - [AFHTTPRequestSerializer serializer] // 負責序列化請求 - [AFJSONResponseSerializer serializer] // 負責序列化響應
從這個初始化方法的調用棧,咱們能夠很是清晰地瞭解這個框架的結構:
其中 AFURLSessionManager
是 AFHTTPSessionManager
的父類
AFURLSessionManager
負責生成 NSURLSession
的實例,管理 AFSecurityPolicy
和 AFNetworkReachabilityManager
,來保證請求的安全和查看網絡鏈接狀況,它有一個 AFJSONResponseSerializer
的實例來序列化 HTTP 響應
AFHTTPSessionManager
有着本身的 AFHTTPRequestSerializer
和 AFJSONResponseSerializer
來管理請求和響應的序列化,同時依賴父類提供的接口保證安全、監控網絡狀態,實現發出 HTTP 請求這一核心功能
初始化方法很好地揭示了 AFNetworking 整個框架的架構,接下來咱們要經過分析另外一個方法 - GET:parameters:process:success:failure:
的調用棧,看一下 HTTP 請求是如何發出的:
- [AFHTTPSessionManager GET:parameters:process:success:failure:] - [AFHTTPSessionManager dataTaskWithHTTPMethod:parameters:uploadProgress:downloadProgress:success:failure:] // 返回 NSURLSessionDataTask #1 - [AFHTTPRequestSerializer requestWithMethod:URLString:parameters:error:] // 返回 NSMutableURLRequest - [AFURLSessionManager dataTaskWithRequest:uploadProgress:downloadProgress:completionHandler:] // 返回 NSURLSessionDataTask #2 - [NSURLSession dataTaskWithRequest:] // 返回 NSURLSessionDataTask #3 - [AFURLSessionManager addDelegateForDataTask:uploadProgress:downloadProgress:completionHandler:] - [AFURLSessionManagerTaskDelegate init] - [AFURLSessionManager setDelegate:forTask:] - [NSURLSessionDataTask resume]
在這裏 #1
#2
#3
處返回的是同一個 data task,咱們能夠看到,在 #3
處調用的方法 - [NSURLSession dataTaskWithRequest:]
和只使用 NSURLSession
發出 HTTP 請求時調用的方法 - [NSURLSession dataTaskWithRequest:completionHandler:]
差很少。在這個地方返回 data task 以後,咱們再調用 - resume
方法執行請求,並在某些事件執行時通知代理 AFURLSessionManagerTaskDelegate
AFNetworking 實際上只是對 NSURLSession
高度地封裝, 提供一些簡單易用的 API 方便咱們在 iOS 開發中發出網絡請求並在其上更快地構建網絡層組件並提供合理的接口.
到這裏,這一篇文章從上到下對 AFNetworking 是如何調用的進行了一個簡單的概述,我會在隨後的文章中會具體介紹 AFNetworking 中的每個模塊,瞭解它們是如何工做,而且如何合理地組織到一塊兒的。
關於其餘 AFNetworking 源代碼分析的其餘文章:
關注倉庫,及時得到更新:iOS-Source-Code-Analyze
Blog: Draveness