iOS - AFNetworking 網絡請求


前言

  • 在 iOS 開發中,一般情況下,簡單的向某個 Web 站點簡單的頁面提交請求並獲取服務器的響應,用 Xcode 自帶的 NSURLConnection 是能勝任的。但是,在絕大部分下我們所需要訪問的 Web 頁面則是屬於那種受到權限保護的頁面,並不是有一個簡單的 URL 可以訪問的。這就涉及到了 Session 和 Cookie 的處理了,在此時使用 NSURLConnection 也是能夠達到要求的,只是其中處理起來的復雜度和難度就提升了。為了更好的處理向 Web 站點的請求,包括處理 Session,Cookie 等細節問題,使用 AFNetworking 則是更好的選擇。

      1. Session:中文有譯作時域的,就是指某個客戶端從訪問服務器起到停止訪問這一段的時間間隔被稱為時域。
      1. Cookie:由服務器發送給客戶端,把 Cookie 的 key:value 值儲存在本地文件夾下,當下次請求的時候能夠直接發送 Cookie 獲得權限驗證。

1、AFNetworking

1.1 AFNetworking 特點

  • AFNetworking 是一個討人喜歡的網絡庫,適用於 iOS,Mac OS X 以及 Watch OS。
  • AFNetworking 構建在 NSURLSession,NSOperation,以及其他熟悉的 Foundation 技術之上。它擁有良好的架構,豐富的 API,以及模塊化構建方式,使得使用起來非常輕松。
  • AFNetworking 可以用於發送 HTTP 請求,接收 HTTP 的響應,但是不會緩存服務器的響應,不能執行 HTML 頁面中的 JAvascript 代碼。
  • AFNetworking 內置支持 JSON,Plist 文件和 XML 文件的半自動序列化和反序列化,可以對 JSON 格式的請求響應數據自動做反序列化,XML 格式數據需要手動反序列化,使用比較方便。
  • AFNetworking 中回調函數將在主線程中進行,程序員不需要關心線程間通訊問題。
  • AFNetworking 具有完善的錯誤處理機制。

1.2 AFNetworking 官方使用建議

  • 建立 AFHTTPSesssionManager 的單例子類,統一管理全局的所有網絡訪問。

    • NetworkTools.h

      	#import <AFNetworking/AFNetworking.h>
      
      	@interface NetworkTools : AFHTTPSessionManager
      
      	+ (instancetype)sharedNetworkTools;
      
      	@end
      
    • NetworkTools.m

      	@implementation NetworkTools
      
      	+ (instancetype)sharedNetworkTools {
          	static NetworkTools *tools;
          
          	static dispatch_once_t onceToken;
          	dispatch_once(&onceToken, ^{
              
              	// baseURL 的目的,就是讓后續的網絡訪問直接使用 相對路徑即可,baseURL 的路徑一定要有 / 結尾
              	NSURL *baseURL = [NSURL URLWithString:@"http://c.m.163.com/"];
              
              	NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
              
              	tools = [[self alloc] initWithBaseURL:baseURL sessionConfiguration:config];
              
              	// 修改 解析數據格式 能夠接受的內容類型 - 官方推薦的做法,民間做法:直接修改 AFN 的源代碼
              	tools.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", 
              	                                                                        @"text/json", 
              	                                                                        @"text/javascript", 
              	                                                                        @"text/html", 
              	                                                                        nil];
          	});
          	return tools;
      	}
      
      	@end
      

1.3 AFNetworking 系統需求

AFNetworking Version Minimum iOS Target Target Notes
3.x iOS 7 Xcode 7+ is required. NSURLConnectionOperation support has been removed.
2.6 -> 2.6.3 iOS 7 Xcode 7+ is required.
2.0 -> 2.5.4 iOS 6 Xcode 5+ is required. NSURLSession subspec requires iOS 7 or OS X 10.9.
1.x iOS 5
0.10.x iOS 4

1.4 AFNetworking 框架結構

    1. V 2.5.4:
    	NSURLConnection                                             對 NSURLConnection 網絡請求的封裝(iOS 9.0 DEPRECATED)
    	 
    	  	AFURLConnectionOperation
    	  	AFHTTPRequestOperation
    	  	AFHTTPRequestOperationManager
    	
    	NSURLSession                                                對 NSURLSession 網絡請求的封裝(iOS 7.0 AVAILABLE)
    	
    	  	AFURLSessionManager
    	  	AFHTTPSessionManager
    	
    	Serialization                                               序列化 & 反序列化 格式
    	
    	  	<AFURLRequestSerialization>                              發送給服務器的數據格式(序列化)
    	  		AFHTTPRequestSerializer                               二進制           默認
    	  		AFJSONRequestSerializer                               JSON            POST JSON
    	  		AFPropertyListRequestSerializer                       Plist           蘋果專有,極少用
    	
    	  	<AFURLResponseSerialization>                             從服務器接收的數據格式(反序列化)
    	  		AFHTTPResponseSerializer                              二進制
    	  		AFJSONResponseSerializer                              JSON            默認
    	  		AFXMLParserResponseSerializer                         XMLParser       SAX 解析
    	  		AFXMLDocumentResponseSerializer (Mac OS X)            XMLDocument     DOM 解析
    	  		AFPropertyListResponseSerializer                      Plist           蘋果專有,極少用
    	  		AFImageResponseSerializer                             Image           圖片
    	  		AFCompoundResponseSerializer                          Compound        組合的
    	
    	Additional Functionality                                     輔助功能
    	
    	  	AFSecurityPolicy                                          安全策略
    	  	AFNetworkReachabilityManager                              網絡狀態監測
    	
    	UIKit+AFNetworking                                           AFNetworking 為相應的 UIKit 控件添加的分類。
    
    1. V 3.1.0:
    	NSURLSession                                                對 NSURLSession 網絡請求的封裝(iOS 7.0 AVAILABLE)
    	
    	  	AFURLSessionManager
    	  	AFHTTPSessionManager
    	 
    	Serialization                                               序列化 & 反序列化 格式
    	
    	  	<AFURLRequestSerialization>                              發送給服務器的數據格式(序列化)
    	  		AFHTTPRequestSerializer                               二進制           默認
    	  		AFJSONRequestSerializer                               JSON            POST JSON
    	  		AFPropertyListRequestSerializer                       Plist           蘋果專有,極少用
    	
    	  	<AFURLResponseSerialization>                             從服務器接收的數據格式(反序列化)
    	  		AFHTTPResponseSerializer                              二進制
    	  		AFJSONResponseSerializer                              JSON            默認
    	  		AFXMLParserResponseSerializer                         XMLParser       SAX 解析
    	  		AFXMLDocumentResponseSerializer (Mac OS X)            XMLDocument     DOM 解析
    	  		AFPropertyListResponseSerializer                      Plist           蘋果專有,極少用
    	  		AFImageResponseSerializer                             Image           圖片
    	  		AFCompoundResponseSerializer                          Compound        組合的
    	 
    	Additional Functionality                                     輔助功能
    	
    	  	AFSecurityPolicy                                          安全策略
    	  	AFNetworkReachabilityManager                              網絡狀態監測
    	
    	UIKit+AFNetworking                                           AFNetworking 為相應的 UIKit 控件添加的分類。
    
  • 3)NSURLConnection 網絡請求封裝:

    	iOS 9.0 DEPRECATED
    	
    	1> AFHTTPRequestOperationManager:
    	 
    	  	屬性:
    	  		requestSerializer   :設置請求的數據格式
    	  		responseSerializer  :設置響應的數據格式
    	 
    	  		reachabilityManager :網絡連接狀態管理器,監控網絡連接狀態
    	 
    	  	方法:
    	  		HTTPRequestOperationWithRequest:如果需要在請求中設置額外的屬性,例如:身份驗證,提前准備好 request ,調用此方法就可以了
    	 
    	  		manager :實例化 HTTP Reuqest 管理器
    	 
    	  		GET     :GET 請求
    	  		HEAD    :HEAD 請求
    	  		POST    :POST 請求,constructingBodyWithBlock:POST 上傳文件用的
    	  		PUT     :PUT 請求
    	  		PATCH   :PATCH 請求,RESTFul 的一個方法,極少用
    	  		DELETE  :DELETE 請求
    	 
    	  		所有的方法:參數字典
    	                   成功回調
    	                   失敗回調
    	                   URL 都是使用字符串來傳遞的
    
    1. NSURLSession 網絡請求封裝:
    	iOS 7.0 AVAILABLE
    	    
    	1> 說明:
    	 
    		基於指定的 NSURLSessionConfiguration 創建並管理一個 NSURLSession 對象。
    		遵守 NSURLSessionTaskDelegate、NSURLSessionDataDelegate、NSURLSessionDownloadDelegate 和 NSURLSessionDelegate 協議。
    	 
    	2> 初始化:
    	 
    		初始化 :- (instancetype)initWithSessionConfiguration:(NSURLSessionConfiguration *)configuration
    		取消   :- (void)invalidateSessionCancelingTasks:(BOOL)cancelPendingTasks;
    	 
    	3> 任務:
    	 
    		數據任務:dataTaskWithRequest:
    	 
    		上傳任務:
    	           從文件上傳   :uploadTaskWithRequest:fromFile:
    	           從數據上傳   :uploadTaskWithRequest:fromData:
    	           從數據流上傳 :uploadTaskWithStreamedRequest:
    	 
    		下載任務:
    	           使用指定的請求創建下載任務 :downloadTaskWithRequest:
    	           使用續傳數據創建下載任務   :downloadTaskWithResumeData:
    	 
    		任務進度:
    	           上傳進度:- (NSProgress *)uploadProgressForTask:(NSURLSessionUploadTask *)uploadTask;
    	           下載進度:- (NSProgress *)downloadProgressForTask:(NSURLSessionDownloadTask *)downloadTask;
    	 
    	4> 代理回調:
    	 
    		<1> 會話代理回調:
    	 
    			設置管理的會話無效回調方法:
    	 
    				- (void)setSessionDidBecomeInvalidBlock:(void (^)(NSURLSession *session, NSError *error))block;
    	 
    					block 參數:
    						session :會話
    						error   :導致會話無效相關的錯誤
    	 
    					設置當管理的會話無效時執行的 block。
    	 
    			設置需要身份驗證回調方法:
    	 
    				- (void)setSessionDidReceiveAuthenticationChallengeBlock:
    				                            (NSURLSessionAuthChallengeDisposition (^)(NSURLSession *session,
    				                                                      NSURLAuthenticationChallenge *challenge, 
    				                                                 NSURLCredential * __autoreleasing *credential))block;
    	 				
    					block 參數:
    						session    :會話
    						challenge  :身份驗證質詢
    						credential :指向憑據的指針,該憑據用於解決身份驗證
    	 
    					block 返回值:
    						返回身份驗證的配置情況
    	 
    					設置當連接需要身份驗證質詢時執行的 block。
    	 
    		<2> 任務代理回調:
    	 
    			設置上傳流回調方法:
    	 
    				- (void)setTaskNeedNewBodyStreamBlock:(NSInputStream * (^)(NSURLSession *session, NSURLSessionTask *task))block;
    	 
    					block 返回值:
    						要上傳文件的 NSInputStream。
    	 
    					設置一個請求體二進制流發送至遠程服務器時執行的 block。
    	 
    			設置重定向回調方法:
    	 
    				- (void)setTaskWillPerformHTTPRedirectionBlock:(NSURLRequest * (^)(NSURLSession *session, 
    				                                                               NSURLSessionTask *task, 
    				                                                                  NSURLResponse *response, 
    				                                                                   NSURLRequest *request))block;
    	 
    	            	block 參數:
    	               	session  :會話
    	                	task     :任務
    	                	response :重定向響應
    	                	request  :要重定向的請求
    	 
    	            	block 返回值:
    	                	返回導致重定向的請求 NSURLRequest
    	 
    	            	設置 HTTP 請求嘗試重定向到其他 URL 時執行的 block。
    	 
    			設置身份驗證質詢回調方法:
    	 
    				- (void)setTaskDidReceiveAuthenticationChallengeBlock:
    				                         (NSURLSessionAuthChallengeDisposition (^)(NSURLSession *session, 
    				                                                               NSURLSessionTask *task, 
    				                                                   NSURLAuthenticationChallenge *challenge, 
    				                                              NSURLCredential * __autoreleasing *credential))block;
    	 				
    	            	block 參數:
    	                	session    :會話
    	                	task       :任務
    	                	challenge  :身份驗證質詢
    	                	credential :指向解決驗證需要使用憑據的指針
    	 
    	            	block 返回值:
    	                	返回對身份驗證請求質詢的處置
    	 
    	            	設置接收到特定身份驗證質詢時執行的 block。
    	 
    			設置上傳進度回調方法:
    	 
    				- (void)setTaskDidSendBodyDataBlock:(void (^)(NSURLSession *session, 
    				                                          NSURLSessionTask *task, 
    				                                                   int64_t bytesSent, 
    				                                                   int64_t totalBytesSent, 
    				                                                   int64_t totalBytesExpectedToSend))block;
    	 
    	            	block 參數:
    	                	session                  :會話
    	                	task                     :任務
    	                	bytesSent                :本次上傳字節數
    	                	totalBytesSent           :已經上傳的字節數
    	                	totalBytesExpectedToSend :總字節數
    	 
    	            	設置跟蹤上傳進度要執行的 block。
    	 
    			設置任務完成回調方法:
    	 
    				- (void)setTaskDidCompleteBlock:(void (^)(NSURLSession *session, NSURLSessionTask *task, NSError *error))block;
    	 
    	            	block 參數:
    	                	session :會話
    	                	task    :任務
    	                	error   :任務執行過程中出現的錯誤
    	 
    	            	設置特定任務完成后執行的 block。
    	 
    		<3> 數據任務代理回調:
    	 
    			設置接收到響應回調方法:
    	 
    				- (void)setDataTaskDidReceiveResponseBlock:(NSURLSessionResponseDisposition (^)(NSURLSession *session, 
    				                                                                        NSURLSessionDataTask *dataTask, 
    				                                                                               NSURLResponse *response))block;
    	 
    	            	block 參數:
    	                	session  :會話
    	                	dataTask :任務
    	                	response :接收到的響應
    	 
    	            	block 返回值:
    	                	返回對會話響應的處置
    	 
    	            	設置數據任務接收到響應時執行的 block。
    	 
    			設置成為下載任務回調方法:
    	 
    				- (void)setDataTaskDidBecomeDownloadTaskBlock:(void (^)(NSURLSession *session, 
    				                                                NSURLSessionDataTask *dataTask, 
    				                                            NSURLSessionDownloadTask *downloadTask))block;
    	 
    	            	block 參數:
    	                	session      :會話
    	                	dataTask     :任務
    	                	downloadTask :成為的下載任務
    	 
    	            	設置數據任務成為下載任務時執行的 block。
    	 
    			設置接收到數據回調方法:
    	 
    				- (void)setDataTaskDidReceiveDataBlock:(void (^)(NSURLSession *session, NSURLSessionDataTask *dataTask, NSData *data))block;
    	 
    	            	block 參數:
    	                	session  :會話
    	                	dataTask :任務
    	                	data     :接收的數據
    	 
    	            	設置數據任務接收到數據時執行的 block。
    	
    			設置緩存行為回調方法:
    	 
    				- (void)setDataTaskWillCacheResponseBlock:(NSCachedURLResponse * (^)(NSURLSession *session, 
    				                                                             NSURLSessionDataTask *dataTask, 
    				                                                              NSCachedURLResponse *proposedResponse))block;
    	 
    	            	block 參數:
    	                	session          :會話
    	                	dataTask         :任務
    	                	proposedResponse :建議緩存的 URL 響應
    		
    	            	block 返回值:
    	                	返回要緩存的響應
    	 
    	            	設置確定數據任務的緩存行為執行的 block。
    	 
    			設置入隊消息提交回調方法:
    	 
    				- (void)setDidFinishEventsForBackgroundURLSessionBlock:(void (^)(NSURLSession *session))block;
    	 
    	            	block 參數:
    	                	session:會話
    	
    	            	設置會話的所有入隊消息已經被提交時執行一次的 block。
    
    		<4> 下載任務代理回調:
    	 
    			設置下載完成回調方法:
    	 
    				- (void)setDownloadTaskDidFinishDownloadingBlock:(NSURL * (^)(NSURLSession *session, 
    				                                                  NSURLSessionDownloadTask *downloadTask, 
    				                                                                     NSURL *location))block;
    	 
    	            	block 參數:
    	                	session      :會話
    	                	downloadTask :下載任務
    	                	location     :保存下載文件的臨時位置
    	
    	            	block 返回值:
    	                	下載文件被移動到的 URL
    	
    	            	設置下載任務完成后執行的 block。
    	 
    			設置下載進度回調方法:
    	 
    				- (void)setDownloadTaskDidWriteDataBlock:(void (^)(NSURLSession *session, 
    				                                       NSURLSessionDownloadTask *downloadTask, 
    				                                                        int64_t bytesWritten, 
    				                                                        int64_t totalBytesWritten, 
    				                                                        int64_t totalBytesExpectedToWrite))block;
    	 
    	            	block 參數:
    	                	session                   :會話
    	                	downloadTask              :下載任務
    	                	bytesWritten              :本次下載字節數
    	                	totalBytesWritten         :已經下載的字節數
    	                	totalBytesExpectedToWrite :總下載字節數
    	
    	            	設置跟蹤下載進度重復執行的 block,該 block 可能會被調用多次,並在會話管理器操作隊列中執行。
    	 
    			設置下載續傳回調方法:
    	 
    				- (void)setDownloadTaskDidResumeBlock:(void (^)(NSURLSession *session, 
    				                                    NSURLSessionDownloadTask *downloadTask, 
    				                                                     int64_t fileOffset, 
    				                                                     int64_t expectedTotalBytes))block;
    		
    	            	block 參數:
    	                	session            :會話
    	                	downloadTask       :下載任務
    	                	fileOffset         :續傳下載的文件偏移位置
    	                	expectedTotalBytes :總下載字節數
    	
    	            	設置下載任務續傳時執行的 blok。
    	
    	5> 通知:
    	 
    		<1> 通知:
    			AFNetworkingTaskDidResumeNotification                 :任務繼續通知
    			AFNetworkingTaskDidCompleteNotification               :任務結束執行通知
    			AFNetworkingTaskDidSuspendNotification                :任務暫停執行通知
    			AFURLSessionDidInvalidateNotification                 :網絡會話無效通知
    			AFURLSessionDownloadTaskDidFailToMoveFileNotification :會話的下載任務將臨時下載文件移動指定目錄發生錯誤通知
    	 
    		<2> 通知鍵值:
    			AFNetworkingTaskDidCompleteResponseDataKey            :任務的原始響應數據
    			AFNetworkingTaskDidCompleteSerializedResponseKey      :任務響應數據的反序列化對象
    			AFNetworkingTaskDidCompleteResponseSerializerKey      :響應序列化器用於反序列化響應數據
    			AFNetworkingTaskDidCompleteAssetPathKey               :與下載任務關聯的文件路徑
    			AFNetworkingTaskDidCompleteErrorKey                   :與任務或者響應反序列化關聯的錯誤
    
    1. AFNetworking 常用數據格式組合設置:
    • AFN 內置支持 JSON,Plist 文件和 XML 文件的半自動序列化和反序列化,可以對 JSON 格式的請求響應數據自動做反序列化,XML 格式數據需要手動反序列化,使用比較方便。AFN 在反序列化數據之前,會判斷服務器返回的 content-Type,如果 content-Type 不符合要求,就放棄反序列化。

    • AFN 默認可以接收的類型:

      • application/json
      • text/json
      • text/javascript
    • 1> 發送二進制數據,接收 JSON,最常用的網絡數據格式組合:

      • 發送數據:
        • 二進制數據:AFHTTPRequestSerializer(默認)
      • 接收數據:
        • JSON 數據:AFJSONResponseSerializer(默認)
    • 2> 發送二進制數據,接收 XML:

      • 發送數據:
        • 二進制數據:AFHTTPRequestSerializer(默認)
      • 接收數據:
        • XML SAX 解析:AFXMLParserResponseSerializer
        • XML DOM 解析:AFHTTPResponseSerializer
    • 3> 發送二進制數據,接收二進制數據(下載...):

      • 發送數據:
        • 二進制數據:AFHTTPRequestSerializer(默認)
      • 接收數據:
        • 二進制數據:AFHTTPResponseSerializer
    • 4> 發送 JSON 數據,接收 JSON:

      • 發送數據:
        • JSON 數據:AFJSONRequestSerializer
      • 接收數據:
        • JSON 數據:AFJSONResponseSerializer(默認)
    • 5> 接收 圖像:

      • 基本上都使用 SDWebImage,緩存做的比 AFN 的要好一些
    1. AFSecurityPolicy 安全策略:
    • NSURLConnection 已經封裝了 https 連接的建立、數據的加密解密功能,我們直接使用 NSURLConnection 是可以訪問 https 網站的,但 NSURLConnection 並沒有驗證證書是否合法,無法避免中間人攻擊。要做到真正安全通訊,需要我們手動去驗證服務端返回的證書,AFNetworking 中 AFSecurityPolicy 封裝了證書驗證的過程,讓用戶可以輕易使用,除了去系統信任 CA 機構列表驗證,還支持 SSL Pinning 方式的驗證。

    • 1> AFSecurityPolicy 安全策略模式:

      • AFSSLPinningModeNone:

        • 這個模式表示不做 SSL pinning,只跟瀏覽器一樣在系統的信任機構列表里驗證服務端返回的證書。若證書是信任機構簽發的就會通過,若是自己服務器生成的證書,這里是不會通過的。
      • AFSSLPinningModeCertificate:

        • 這個模式表示用證書綁定方式驗證證書,需要客戶端保存有服務端的證書拷貝,這里驗證分兩步,第一步驗證證書的域名/有效期等信息,第二步是對比服務端返回的證書跟客戶端返回的是否一致。
      • AFSSLPinningModePublicKey:

        • 這個模式同樣是用證書綁定方式驗證,客戶端要有服務端的證書拷貝,只是驗證時只驗證證書里的公鑰,不驗證證書的有效期等信息。只要公鑰是正確的,就能保證通信不會被竊聽,因為中間人沒有私鑰,無法解開通過公鑰加密的數據。
    • 2> HTTPS:

      • 代理方法:

        	- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge 
        	                                             completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, 
        	                                                        NSURLCredential *))completionHandler
        
      • 參數:

        	NSURLAuthenticationChallenge:身份驗證質詢
        
        		protectionSpace:保護空間,在信任受保護空間中的憑據之前,無法繼續后續的網絡請求。
        
        		NSURLSessionAuthChallengeDisposition:對憑據的處置
        
        		NSURLSessionAuthChallengeUseCredential                  :使用指定的憑據。
        		NSURLSessionAuthChallengePerformDefaultHandling         :默認處理,憑據參數會被忽略。
        		NSURLSessionAuthChallengeCancelAuthenticationChallenge  :整個請求將被忽略。
        		NSURLSessionAuthChallengeRejectProtectionSpace          :拒絕本次憑據,嘗試下一次驗證保護空間。
        
      • 代碼:

        	if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
        
        		NSURLCredential *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
        
        		completionHandler(NSURLSessionAuthChallengeUseCredential, credential);
        	}
        
    1. AFNetworkReachabilityManager 網絡狀態監測:
    • 狀態:

      	AFNetworkReachabilityStatusUnknown          = -1,               網絡狀態未知
      	AFNetworkReachabilityStatusNotReachable     = 0,                無網絡連接
      	AFNetworkReachabilityStatusReachableViaWWAN = 1,                無線網絡(蜂窩移動網絡)
      	AFNetworkReachabilityStatusReachableViaWiFi = 2,                WiFi 網絡
      
    • 屬性:

      	networkReachabilityStatus                                       獲取網絡連接狀態
      
      	isReachable;                                                    網絡是否連接
      	isReachableViaWiFi;                                             WiFi 是否連接
      	isReachableViaWWAN;                                             蜂窩網絡 是否連接
      
    • 方法:

      	+ (instancetype)sharedManager;                                  實例化網絡狀態監測管理器
      	+ (instancetype)managerForDomain:(NSString *)domain;            實例化 相對於某個域名 網絡狀態監測管理器
      	+ (instancetype)managerForAddress:(const void *)address;        實例化 相對於某個地址 網絡狀態監測管理器
      
      	- (void)startMonitoring;                                        開啟監聽網絡狀態
      	- (void)stopMonitoring;                                         關閉網絡狀態監聽
      
      	- (NSString *)localizedNetworkReachabilityStatusString;         獲取本地化網絡狀態字符串
      
      	AFStringFromNetworkReachabilityStatus(AFNetworkReachabilityStatus status);                          轉換網絡狀態為字符串格式
      
      	- (void)setReachabilityStatusChangeBlock:(void (^)(AFNetworkReachabilityStatus status))block;       網絡狀態改變回調
      
    • 通知:

      	AFNetworkingReachabilityDidChangeNotification                   網絡狀態改變通知
      	AFNetworkingReachabilityNotificationStatusItem                  網絡狀態項
      

2、AFNetworking 的添加

3、AFNetworking 的設置

  • Objective-C

    • Manager 的創建

      	// AFHTTPSessionManager
      
          	AFHTTPSessionManager *manager1 = [AFHTTPSessionManager manager];
      
          	NSURL *baseURL2 = [NSURL URLWithString:@"http://192.168.88.200"];
          	AFHTTPSessionManager *manager2 = [[AFHTTPSessionManager alloc] initWithBaseURL:baseURL2];
      
          	NSURL *baseURL3 = [NSURL URLWithString:@"http://192.168.88.200"];
          	NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
          	AFHTTPSessionManager *manager3 = [[AFHTTPSessionManager alloc] initWithBaseURL:baseURL3 sessionConfiguration:config];
      
      	// AFURLSessionManager
      
          	AFURLSessionManager *manager4 = [[AFURLSessionManager alloc] 
          	                                  initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
      
      		// 取消掛起的 task
          	[[AFURLSessionManager alloc] invalidateSessionCancelingTasks:YES];                  
      
    • URLRequest 的創建

      	NSURL *url1 = [NSURL URLWithString:@"http://192.168.88.200:8080/MJServer/video?type=JSON"];
      	NSURL *url2 = [NSURL URLWithString:@"http://192.168.88.200:8080/MJServer/video"];
      
      	NSString *urlStr = @"http://192.168.88.200:8080/MJServer/video";
      	NSDictionary *params = @{@"type":@"JSON"};
      
      	// GET 創建方式
      
          	NSURLRequest *request1 = [NSURLRequest requestWithURL:url1];
      
          	NSURLRequest *request2 = [[AFHTTPRequestSerializer serializer] requestWithMethod:@"GET" 
          	                                                                       URLString:urlStr 
          	                                                                      parameters:params 
          	                                                                           error:NULL];
      
      	// POST 創建方式
      
          	NSMutableURLRequest *request3 = [NSMutableURLRequest requestWithURL:url2];
          	request3.HTTPMethod = @"POST";
          	request3.HTTPBody = [@"type=JSON" dataUsingEncoding:NSUTF8StringEncoding];
      
          	NSURLRequest *request4 = [[AFHTTPRequestSerializer serializer] requestWithMethod:@"POST" 
          	                                                                       URLString:urlStr 
          	                                                                      parameters:params 
          	                                                                           error:NULL];
      
          	NSURLRequest *request5 = [[AFHTTPRequestSerializer serializer] multipartFormRequestWithMethod:@"POST" 
          	                                                                                    URLString:urlStr 
          	                                                                                   parameters:params
          	                                                                  constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
      
          	} error: NULL];
      
    • Request 的設置

      	AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
      
      	NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://192.168.88.200:8080/MJServer/video?type=JSON"]];
      
      	// 設置參數編碼方式
      	/*
      		`NSUTF8StringEncoding` by default
      	*/
      	manager.requestSerializer.stringEncoding = NSUTF8StringEncoding;
      
      	// 設置緩存策略
      	/*
      		`NSURLRequestUseProtocolCachePolicy` by default.
      	*/
      	manager.requestSerializer.cachePolicy = NSURLRequestUseProtocolCachePolicy;
      
       	request.cachePolicy = NSURLRequestUseProtocolCachePolicy;
      
      	// 設置網絡服務類型
      	/*
      		`NSURLNetworkServiceTypeDefault` by default.
      	*/
        	manager.requestSerializer.networkServiceType = NSURLNetworkServiceTypeDefault;
      
       	request.networkServiceType = NSURLNetworkServiceTypeDefault;
      
      	// 設置請求超時時間
      	/*
      		The default timeout interval is 60 seconds.
      	*/
      	manager.requestSerializer.timeoutInterval = 15;
      
      	request.timeoutInterval = 15;
      
      	// 是否允許蜂窩網絡訪問
      	/*
      		`YES` by default.
      	*/
      	manager.requestSerializer.allowsCellularAccess = YES;
      
      	request.allowsCellularAccess = YES;
      
      	// 設置是否應用默認的 Cookies
      	/*
      		`YES` by default.
      	*/
      	manager.requestSerializer.HTTPShouldHandleCookies = YES;
      
      	request.HTTPShouldHandleCookies = YES;
      
      	// 設置是否使用 Pipelining
      	/*
      		`NO` by default.
      	*/
      	manager.requestSerializer.HTTPShouldUsePipelining = NO;
      
      	request.HTTPShouldUsePipelining = NO;
      
      	// 請求頭設置
      	
      	[manager.requestSerializer setValue:@"iPhone" forHTTPHeaderField:@"User-Agent"];
      
      	[request setValue:@"iPhone" forHTTPHeaderField:@"User-Agent"];
      
      	// 設置用戶驗證
      	
      	[manager.requestSerializer setAuthorizationHeaderFieldWithUsername:@"admin" password:@"adminpasswd"];
      
      	NSString *username = @"admin";
      	NSString *password = @"adminpasswd";
      	NSString *userPasswordString = [NSString stringWithFormat:@"%@:%@", username, password];
      	NSData   *userPasswordData = [userPasswordString dataUsingEncoding:NSUTF8StringEncoding];
      	NSString *base64EncodedCredential = [userPasswordData base64EncodedStringWithOptions:0];
      	NSString *authString = [NSString stringWithFormat:@"Basic: %@", base64EncodedCredential];
      
      	[request setValue:authString forHTTPHeaderField:@"Authorization"];
      
      	// 清除用戶驗證信息
      	
      	[manager.requestSerializer clearAuthorizationHeader];
      
      	[request setValue:nil forHTTPHeaderField:@"Authorization"];
      
      	// 設置請求體
      	request.HTTPBody = [@"type=JSON" dataUsingEncoding:NSUTF8StringEncoding];
      
      	// 設置請求模式
      
      		// 單獨設置
      		/*
      			默認是 GET
      		*/
      		request.HTTPMethod = @"POST";
      
      		// 直接設置
      
      		NSString *urlStr = @"http://192.168.88.200:8080/MJServer/video";
      		NSDictionary *parameters = @{@"type":@"XML"};
      
      		NSURLRequest *request1 = [[AFHTTPRequestSerializer serializer] requestWithMethod:@"POST" 
      		                                                                       URLString:urlStr 
      		                                                                      parameters:parameters 
      		                                                                           error:NULL];
      
    • 設置數據請求格式

      	NSString *urlStr = @"http://example.com";
      	NSDictionary *parameters = @{@"foo": @"bar", @"baz": @[@1, @2, @3]};
      
      	AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
      
      	// 二進制 格式
      
          	// POST http://example.com/
          	// Content-Type: application/x-www-form-urlencoded
          
          	// foo=bar&baz[]=1&baz[]=2&baz[]=3
      
          	manager.requestSerializer = [AFHTTPRequestSerializer serializer];      // 默認
      
          	NSURLRequest *request1 = [[AFHTTPRequestSerializer serializer] requestWithMethod:@"POST" 
          	                                                                       URLString:urlStr 
          	                                                                      parameters:parameters 
          	                                                                           error:NULL];
      
      	// JSON 格式
      
          	// POST http://example.com/
          	// Content-Type: application/json
          
          	// {"foo": "bar", "baz": [1,2,3]}
          
          	manager.requestSerializer = [AFJSONRequestSerializer serializer];
      
          	NSURLRequest *request2 = [[AFJSONRequestSerializer serializer] requestWithMethod:@"POST" 
          	                                                                       URLString:urlStr 
          	                                                                      parameters:parameters 
          	                                                                           error:NULL];
      
      	// Plist 格式
      
          	manager.requestSerializer = [AFPropertyListRequestSerializer serializer];
      
          	NSURLRequest *request3 = [[AFPropertyListRequestSerializer serializer] requestWithMethod:@"POST" 
          	                                                                               URLString:urlStr 
          	                                                                              parameters:parameters 
          	                                                                                   error:NULL];
      
    • 設置數據響應格式

      	AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
      
      	AFURLSessionManager *manager1 = [[AFURLSessionManager alloc] 
      	                                  initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
      
      	// 二進制
      	manager.responseSerializer = [AFHTTPResponseSerializer serializer];
      
      	// JSON,默認,application/json, text/json, text/javascript
      	manager.responseSerializer = [AFJSONResponseSerializer serializer];
      
      	// XMLParser,SAX 解析
      	manager.responseSerializer = [AFXMLParserResponseSerializer serializer];
      
      	// Plist
      	manager.responseSerializer = [AFPropertyListResponseSerializer serializer];
      
      	// Image
      	manager.responseSerializer = [AFImageResponseSerializer serializer];
      
      	// Compound
      	manager.responseSerializer = [AFCompoundResponseSerializer serializer];
      
    • AFHTTPSessionManager 請求

      	// GET
      
      		// DEPRECATED_ATTRIBUTE
      		- (nullable NSURLSessionDataTask *)GET:(NSString *)URLString
      		                            parameters:(nullable id)parameters
      		                               success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success
      		                               failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure;
      
      		- (nullable NSURLSessionDataTask *)GET:(NSString *)URLString
      		                            parameters:(nullable id)parameters
      		                              progress:(nullable void (^)(NSProgress *downloadProgress))downloadProgress
      		                               success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success
      		                               failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure;
      
      	// HEAD
      
      		- (nullable NSURLSessionDataTask *)HEAD:(NSString *)URLString
      		                             parameters:(nullable id)parameters
      		                                success:(nullable void (^)(NSURLSessionDataTask *task))success
      		                                failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure;
      
      	// POST
      
      		// DEPRECATED_ATTRIBUTE
          	- (nullable NSURLSessionDataTask *)POST:(NSString *)URLString
      		                             parameters:(nullable id)parameters
      		                                success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success
      		                                failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure;
      
          	- (nullable NSURLSessionDataTask *)POST:(NSString *)URLString
      		                             parameters:(nullable id)parameters
      		                               progress:(nullable void (^)(NSProgress *uploadProgress))uploadProgress
      		                                success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success
      		                                failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure;
      
      		// DEPRECATED_ATTRIBUTE
          	- (nullable NSURLSessionDataTask *)POST:(NSString *)URLString
      		                             parameters:(nullable id)parameters
      		              constructingBodyWithBlock:(nullable void (^)(id <AFMultipartFormData> formData))block
      		                                success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success
      		                                failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure;
      
          	- (nullable NSURLSessionDataTask *)POST:(NSString *)URLString
      		                             parameters:(nullable id)parameters
      		              constructingBodyWithBlock:(nullable void (^)(id <AFMultipartFormData> formData))block
      		                               progress:(nullable void (^)(NSProgress *uploadProgress))uploadProgress
      		                                success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success
      		                                failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure;
      
      	// PUT
      
          	- (nullable NSURLSessionDataTask *)PUT:(NSString *)URLString
      		                            parameters:(nullable id)parameters
      		                               success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success
      		                               failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure;
      
      	// PATCH
      
          	- (nullable NSURLSessionDataTask *)PATCH:(NSString *)URLString
      		                              parameters:(nullable id)parameters
      		                                 success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success
      		                                 failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure;
      
      	// DELETE
      
          	- (nullable NSURLSessionDataTask *)DELETE:(NSString *)URLString
      		                               parameters:(nullable id)parameters
      		                                  success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success
      		                                  failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure;
      
    • AFURLSessionManager 請求

      	// Data Tasks
      
          	- (NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)request
          	                            completionHandler:(nullable void (^)(NSURLResponse *response, 
          	                                                                  id _Nullable responseObject, 
          	                                                                       NSError * _Nullable error))completionHandler;
      
          	- (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;
      
      	// Upload Tasks
      
          	- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request
          	                                         fromFile:(NSURL *)fileURL
          	                                         progress:(nullable void (^)(NSProgress *uploadProgress))uploadProgressBlock
          	                                completionHandler:(nullable void (^)(NSURLResponse *response, 
          	                                                                      id _Nullable responseObject, 
          	                                                                           NSError * _Nullable error))completionHandler;
      
          	- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request
          	                                         fromData:(nullable NSData *)bodyData
          	                                         progress:(nullable void (^)(NSProgress *uploadProgress))uploadProgressBlock
          	                                completionHandler:(nullable void (^)(NSURLResponse *response, 
          	                                                                      id _Nullable responseObject, 
          	                                                                           NSError * _Nullable error))completionHandler;
      
          	- (NSURLSessionUploadTask *)uploadTaskWithStreamedRequest:(NSURLRequest *)request
          	                                                 progress:(nullable void (^)(NSProgress *uploadProgress))uploadProgressBlock
          	                                        completionHandler:(nullable void (^)(NSURLResponse *response, 
          	                                                                              id _Nullable responseObject, 
          	                                                                                   NSError * _Nullable error))completionHandler;
      
      	// Download Tasks
      
          	- (NSURLSessionDownloadTask *)downloadTaskWithRequest:(NSURLRequest *)request
          	                                             progress:(nullable void (^)(NSProgress *downloadProgress))downloadProgressBlock
          	                                          destination:(nullable NSURL * (^)(NSURL *targetPath, 
          	                                                                    NSURLResponse *response))destination
          	                                    completionHandler:(nullable void (^)(NSURLResponse *response, 
          	                                                                                 NSURL * _Nullable filePath, 
          	                                                                               NSError * _Nullable error))completionHandler;
      
          	- (NSURLSessionDownloadTask *)downloadTaskWithResumeData:(NSData *)resumeData
                                                            progress:(nullable void (^)(NSProgress *downloadProgress))downloadProgressBlock
                                                         destination:(nullable NSURL * (^)(NSURL *targetPath, 
                                                                                   NSURLResponse *response))destination
                                                   completionHandler:(nullable void (^)(NSURLResponse *response, 
                                                                                                NSURL * _Nullable filePath, 
                                                                                              NSError * _Nullable error))completionHandler;
      

4、AFNetworking 網絡狀態監測

  • Objective-C

    • 網絡連接狀態:

      	AFNetworkReachabilityStatusUnknown          = -1,               網絡狀態未知
      	AFNetworkReachabilityStatusNotReachable     = 0,                無網絡連接
      	AFNetworkReachabilityStatusReachableViaWWAN = 1,                無線網絡(蜂窩移動網絡)
      	AFNetworkReachabilityStatusReachableViaWiFi = 2,                WiFi 網絡
      
    • 由於檢測網絡有一定的延遲,如果啟動 App 立即去檢測調用 [AFNetworkReachabilityManager sharedManager].networkReachabilityStatus 有可能得到的是 netStatus == AFNetworkReachabilityStatusUnknown; 但是此時明明是有網的,建議在收到監聽網絡狀態回調以后再取 [AFNetworkReachabilityManager sharedManager].networkReachabilityStatus。或者延時調用 [self performSelector:@selector(networkReachability:) withObject:nil afterDelay:0.35f];。

    • 必須開啟監聽,才能獲得網絡狀態。

      • AFNetworkReachabilityManager 方式

        	// 開啟監聽網絡狀態
        	[[AFNetworkReachabilityManager sharedManager] startMonitoring];
        
        	// 關閉網絡狀態監聽
        	[[AFNetworkReachabilityManager sharedManager] stopMonitoring];
        
        	// 監聽網絡狀態回調
        	[[AFNetworkReachabilityManager sharedManager] setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
        
        		// 開啟網絡狀態監聽后,只要網絡狀態發生改變就會調用該 Block 代碼段
        	}];
        
        	// 判斷網絡是否連接
        	BOOL isReachable = [AFNetworkReachabilityManager sharedManager].isReachable;
        
        	// 判斷 WiFi 是否連接
        	BOOL isReachableViaWiFi = [AFNetworkReachabilityManager sharedManager].isReachableViaWiFi;
        
        	// 判斷 無線網絡 是否連接
        	BOOL isReachableViaWWAN = [AFNetworkReachabilityManager sharedManager].isReachableViaWWAN;
        
        	// 獲取網絡連接狀態
        	AFNetworkReachabilityStatus netStatus = [AFNetworkReachabilityManager sharedManager].networkReachabilityStatus;
        
        	// 轉換網絡狀態為字符串格式
        	NSString *netStatusStr1 = AFStringFromNetworkReachabilityStatus(netStatus);
        
        	// 獲取網絡連接狀態
        	NSString *netStatusStr2 = [[AFNetworkReachabilityManager sharedManager] localizedNetworkReachabilityStatusString];
        
      • AFHTTPSessionManager/AFURLSessionManager 方式

        	AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
        
        	AFURLSessionManager * manager = [[AFURLSessionManager alloc] 
        	                                  initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
        
        	// 開啟監聽網絡狀態
        	[manager.reachabilityManager startMonitoring];
        
        	NSOperationQueue *operationQueue = manager.operationQueue;
        
        	[manager.reachabilityManager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
            
            	// 開啟網絡狀態監聽后,只要網絡狀態發生改變就回調用該 Block 代碼段
             
            	NSString *netStatus = AFStringFromNetworkReachabilityStatus(status);
            	NSLog(@"Reachability: %@", netStatus);
            
            	switch (status) {
                	case AFNetworkReachabilityStatusReachableViaWWAN:
                	case AFNetworkReachabilityStatusReachableViaWiFi:
                	
        			// 繼續 queue
                   	[operationQueue setSuspended:NO];
                   	break;
                    
                	case AFNetworkReachabilityStatusNotReachable:
                	default:
                	
        			// 暫停 queue
                   	[operationQueue setSuspended:YES];
                   	break;
            	}
        	}];
        

5、AFNetworking 安全策略設置

  • Objective-C

    • AFSecurityPolicy 方式

      	AFSecurityPolicy *securityPolicy = [AFSecurityPolicy defaultPolicy];
      
      	// 設置是否信任無效或過期的 SSL 證書的服務器。默認為否
      	securityPolicy.allowInvalidCertificates = YES;                                                              
      
      	// 設置安全驗證模式,默認為 AFSSLPinningModeNone
      	securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModePublicKey];                        
      
    • AFHTTPSessionManager/AFURLSessionManager 方式

      	AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
      
      	AFURLSessionManager * manager = [[AFURLSessionManager alloc] 
      	                                  initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
      
      	// 設置是否信任無效或過期的 SSL 證書的服務器。默認為否
      	manager.securityPolicy.allowInvalidCertificates = YES;
      
      	// 設置安全驗證模式,默認為 AFSSLPinningModeNone
      	manager.securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModePublicKey];
      

6、AFHTTPRequestOperationManager 的使用

  • Objective-C

    • Manager 的創建

      	NSURL *baseURL = [NSURL URLWithString:@"http://192.168.88.200"];
      
      	AFHTTPRequestOperationManager *manager1 = [AFHTTPRequestOperationManager manager];
      	
      	AFHTTPRequestOperationManager *manager2 = [[AFHTTPRequestOperationManager alloc] initWithBaseURL:baseURL];
      
    • 設置數據請求格式

      	AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
      
      	// 二進制,默認
      	manager.requestSerializer = [AFHTTPRequestSerializer serializer];
      
      	// JSON
      	manager.requestSerializer = [AFJSONRequestSerializer serializer];
      
      	// Plist
      	manager.requestSerializer = [AFPropertyListRequestSerializer serializer];
      
    • 設置數據響應格式

      	AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
      
      	// 二進制
      	manager.responseSerializer = [AFHTTPResponseSerializer serializer];
      
      	// JSON,默認
      	manager.responseSerializer = [AFJSONResponseSerializer serializer];
      
      	// XMLParser,SAX 解析
      	manager.responseSerializer = [AFXMLParserResponseSerializer serializer];
      
      	// Plist
      	manager.responseSerializer = [AFPropertyListResponseSerializer serializer];
      
      	// Image
      	manager.responseSerializer = [AFImageResponseSerializer serializer];
      
      	// Compound
      	manager.responseSerializer = [AFCompoundResponseSerializer serializer];
      
    • GET 請求

      • 數據請求

        	NSString *urlStr = @"http://192.168.88.200/demo.json";
        
        	AFHTTPRequestOperationManager *manger = [AFHTTPRequestOperationManager manager];
        
        	[manger GET:urlStr parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
            
            	NSLog(@"success: %@ --- %@", responseObject, [responseObject class]);
            
        	} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
            
            	NSLog(@"failure: %@", error);
        	}];
        
      • 文件下載

        	NSString *urlStr = @"http://192.168.88.200/download/file/minion_01.mp4";
        
        	AFHTTPRequestOperationManager *manger = [AFHTTPRequestOperationManager manager];
        	
        	// 設置接收數據的類型為二進制格式
        	manger.responseSerializer = [AFHTTPResponseSerializer serializer];
        
        	[manger GET:urlStr parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
            
            	[responseObject writeToFile:[operation.response.suggestedFilename q_appendDocumentPath] atomically:YES];
            
            	NSLog(@"success: %@", [responseObject class]);
            
        	} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
            
            	NSLog(@"failure: %@", error);
        	}];
        
    • HEAD 請求

      	NSString *urlStr = @"http://192.168.88.200/download/file/minion_01.mp4";
      
      	AFHTTPRequestOperationManager *manger = [AFHTTPRequestOperationManager manager];
      
      	[manger HEAD:urlStr parameters:nil success:^(AFHTTPRequestOperation *operation) {
          
          	NSLog(@"success: %@ --- %lld", operation.response.suggestedFilename, operation.response.expectedContentLength);
          
      	} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
          
          	NSLog(@"failure: %@", error);
      	}];
      
    • POST 請求

      • 數據請求

        	NSString *urlStr = @"http://192.168.88.200:8080/MJServer/video";
        	NSDictionary *params = @{@"type":@"JSON"};
        
        	AFHTTPRequestOperationManager *manger = [AFHTTPRequestOperationManager manager];
        
        	[manger POST:urlStr parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) {
            
            	NSLog(@"success: %@ --- %@", responseObject, [responseObject class]);
            
        	} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
            
            	NSLog(@"failure: %@", error);
        	}];
        
      • 文件上傳

        	NSString *urlStr = @"http://192.168.88.200/upload/upload.php";
        
        	AFHTTPRequestOperationManager *manger = [AFHTTPRequestOperationManager manager];
        
        	[manger POST:urlStr parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
            
            	NSData *fileData = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"HQ_0005.jpg" ofType:nil]];
            	[formData appendPartWithFileData:fileData name:@"userfile" fileName:@"test.jpg" mimeType:@"image/jpg"];
            	[formData appendPartWithFormData:[@"qian" dataUsingEncoding:NSUTF8StringEncoding] name:@"username"];
            
        	} success:^(AFHTTPRequestOperation *operation, id responseObject) {
            
            	NSLog(@"success: %@ --- %@", responseObject, [responseObject class]);
            
        	} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
            
            	NSLog(@"failure: %@", error);
        	}];
        

7、AFHTTPSessionManager 的使用

  • Objective-C

    • Manager 的創建

      	NSURL *baseURL = [NSURL URLWithString:@"http://192.168.88.200"];
      	NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
      
      	AFHTTPSessionManager *manager1 = [AFHTTPSessionManager manager];
      	
      	AFHTTPSessionManager *manager2 = [[AFHTTPSessionManager alloc] initWithBaseURL:baseURL];
      	
      	AFHTTPSessionManager *manager3 = [[AFHTTPSessionManager alloc] initWithBaseURL:baseURL sessionConfiguration:config];
      
    • 設置數據請求格式

      	AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
      
      	// 二進制,默認
      	manager.requestSerializer = [AFHTTPRequestSerializer serializer];
      
      	// JSON
      	manager.requestSerializer = [AFJSONRequestSerializer serializer];
      
      	// Plist
      	manager.requestSerializer = [AFPropertyListRequestSerializer serializer];
      
    • 設置數據響應格式

      	AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
      	    
      	// 二進制
      	manager.responseSerializer = [AFHTTPResponseSerializer serializer];
      
      	// JSON,默認
      	manager.responseSerializer = [AFJSONResponseSerializer serializer];
      
      	// XMLParser,SAX 解析
      	manager.responseSerializer = [AFXMLParserResponseSerializer serializer];
      
      	// Plist
      	manager.responseSerializer = [AFPropertyListResponseSerializer serializer];
      
      	// Image
      	manager.responseSerializer = [AFImageResponseSerializer serializer];
      
      	// Compound
      	manager.responseSerializer = [AFCompoundResponseSerializer serializer];
      
    • Request 設置

      	AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
      
      	// 設置參數編碼方式,`NSUTF8StringEncoding` by default
      	manager.requestSerializer.stringEncoding = NSUTF8StringEncoding;
      
      	// 設置緩存策略,`NSURLRequestUseProtocolCachePolicy` by default.
      	manager.requestSerializer.cachePolicy = NSURLRequestUseProtocolCachePolicy;
      
      	// 設置網絡服務類型,`NSURLNetworkServiceTypeDefault` by default.
      	manager.requestSerializer.networkServiceType = NSURLNetworkServiceTypeDefault;
      
      	// 設置請求超時時間,The default timeout interval is 60 seconds.
      	manager.requestSerializer.timeoutInterval = 15;
      
      	// 是否允許蜂窩網絡訪問,`YES` by default.
      	manager.requestSerializer.allowsCellularAccess = YES;
      
      	// 設置是否應用默認的 Cookies,`YES` by default.
      	manager.requestSerializer.HTTPShouldHandleCookies = YES;
      
      	// 設置是否使用 Pipelining,`NO` by default.
      	manager.requestSerializer.HTTPShouldUsePipelining = NO;
      
      	// 請求頭設置
      
      		// 設置請求頭
          	[manager.requestSerializer setValue:@"iPhone" forHTTPHeaderField:@"User-Agent"];
          
          	// 設置用戶驗證
          	[manager.requestSerializer setAuthorizationHeaderFieldWithUsername:@"admin" password:@"adminpasswd"];
          
          	// 清除用戶驗證信息
          	[manager.requestSerializer clearAuthorizationHeader];
      
    • GET 請求

      • 數據請求

        	NSString *urlStr = @"http://192.168.88.200/demo.json";
            
        	AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
            
        	[manager GET:urlStr parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, 
        	                                                                            id _Nullable responseObject) {
                
        		NSLog(@"success: %@ --- %@", responseObject, [responseObject class]);
                
        	} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
                
        		NSLog(@"failure: %@", error);
        	}];
        
      • 文件下載

        	NSString *urlStr = @"http://192.168.88.200/download/file/minion_01.mp4";
            
        	AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
            
        	// 設置接收數據的類型為二進制格式
        	manager.responseSerializer = [AFHTTPResponseSerializer serializer];                                              
            
        	[manager GET:urlStr parameters:nil progress:^(NSProgress * _Nonnull downloadProgress) {
                
           	float progress = 1.0 * downloadProgress.completedUnitCount / downloadProgress.totalUnitCount;
                
             	dispatch_async(dispatch_get_main_queue(), ^{
              		[self.progressBtn q_setButtonWithProgress:progress lineWidth:10 lineColor:nil 
              	                                                              backgroundColor:[UIColor yellowColor]];
            	});
                
        	} success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
                
            	[responseObject writeToFile:[task.response.suggestedFilename q_appendDocumentPath] atomically:YES];
                
        		NSLog(@"success: %@", [responseObject class]);
                
        	} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
                
            	NSLog(@"failure: %@", error);
        	}];
        
    • HEAD 請求

      	NSString *urlStr = @"http://192.168.88.200/download/file/minion_01.mp4";
      
      	AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
      
      	[manager HEAD:urlStr parameters:nil success:^(NSURLSessionDataTask * _Nonnull task) {
          
          	NSLog(@"success: %@ --- %lld", task.response.suggestedFilename, task.response.expectedContentLength);
          
      	} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
          
          	NSLog(@"failure: %@", error);
      	}];
      
    • POST 請求

      • 數據請求

        	NSString *urlStr = @"http://192.168.88.200:8080/MJServer/video";
        	NSDictionary *params = @{@"type":@"JSON"};
        
        	AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
        
        	[manager POST:urlStr parameters:params 
        	                       progress:nil 
        	                        success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
            
            	NSLog(@"success: %@ --- %@", responseObject, [responseObject class]);
            
        	} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            
            	NSLog(@"failure: %@", error);
        	}];
        
      • 文件上傳

        	NSString *urlStr = @"http://192.168.88.200/upload/upload.php";
        
        	AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
        
        	[manager POST:urlStr parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
            
            	NSData *fileData = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"HQ_0005.jpg" ofType:nil]];
            	[formData appendPartWithFileData:fileData name:@"userfile" fileName:@"test.jpg" mimeType:@"image/jpg"];
            	[formData appendPartWithFormData:[@"qian" dataUsingEncoding:NSUTF8StringEncoding] name:@"username"];
            
        	} progress:^(NSProgress * _Nonnull uploadProgress) {
            
            	float progress = 1.0 * uploadProgress.completedUnitCount / uploadProgress.totalUnitCount;
            	dispatch_async(dispatch_get_main_queue(), ^{
                	[self.progressBtn q_setButtonWithProgress:progress lineWidth:10 lineColor:nil 
                	                                                          backgroundColor:[UIColor yellowColor]];
            	});
            
        	} success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
            
            	NSLog(@"success: %@ --- %@", responseObject, [responseObject class]);
            
        	} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            
            	NSLog(@"failure: %@", error);
        	}];
        

8、AFURLSessionManager 的使用

  • Objective-C

    • Manager 的創建

      	// 創建 manager
      	AFURLSessionManager *manager = [[AFURLSessionManager alloc] 
      	                                 initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
      
      	// 取消掛起的 task
      	[[AFURLSessionManager alloc] invalidateSessionCancelingTasks:YES];
      
    • 設置數據響應格式

      	AFURLSessionManager *manager = [[AFURLSessionManager alloc] 
      	                                 initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
      
      	// 二進制
      	manager.responseSerializer = [AFHTTPResponseSerializer serializer];
      
      	// JSON,默認
      	manager.responseSerializer = [AFJSONResponseSerializer serializer];
      
      	// XMLParser,SAX 解析
      	manager.responseSerializer = [AFXMLParserResponseSerializer serializer];
      
      	// Plist
      	manager.responseSerializer = [AFPropertyListResponseSerializer serializer];
      
      	// Image
      	manager.responseSerializer = [AFImageResponseSerializer serializer];
      
      	// Compound
      	manager.responseSerializer = [AFCompoundResponseSerializer serializer];
      
    • 獲取上傳下載進度

      	AFURLSessionManager *manager = [[AFURLSessionManager alloc] 
      	                                 initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
      
      	// 獲取上傳進度
      	NSProgress *uploadProgress = [manager uploadProgressForTask:uploadTask];
      
      	// 獲取下載進度
      	NSProgress *downloadProgress = [manager uploadProgressForTask:downloadTask];
      
    • Data Tasks

      • GET 數據請求

        	NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:
        	                                                           @"http://192.168.88.200:8080/MJServer/video?type=JSON"]];
        
        	AFURLSessionManager *manager = [[AFURLSessionManager alloc] 
                                         initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
        
        	[[manager dataTaskWithRequest:request completionHandler:^(NSURLResponse * _Nonnull response, 
        	                                                                     id _Nullable responseObject, 
        	                                                                NSError * _Nullable error) {
            
            	if (error == nil && responseObject != nil) {
                	NSLog(@"success: %@ --- %@", responseObject, [responseObject class]);
            	} else {
                	NSLog(@"failure: %@", error);
            	}
        	}] resume];
        
      • POST 數據請求

        	NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:
        	                                                                     @"http://192.168.88.200:8080/MJServer/video"]];
        	request.HTTPMethod = @"POST";
        	request.HTTPBody = [@"type=JSON" dataUsingEncoding:NSUTF8StringEncoding];
        
        	AFURLSessionManager *manager = [[AFURLSessionManager alloc] 
                                         initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
        
        	[[manager dataTaskWithRequest:request completionHandler:^(NSURLResponse * _Nonnull response, 
        	                                                                     id _Nullable responseObject, 
        	                                                                NSError * _Nullable error) {
            
            	if (error == nil && responseObject != nil) {
                	NSLog(@"success: %@ --- %@", responseObject, [responseObject class]);
            	} else {
                	NSLog(@"failure: %@", error);
            	}
        	}] resume];
        
    • Upload Tasks

      • POST 文件上傳

        • 文件數據封裝使用到第三方框架 QExtension,具體實現代碼見 GitHub 源碼 QExtension
        	NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:
        	                                                                        @"http://192.168.88.200/upload/upload.php"]];
        	request.HTTPMethod = @"POST";
        
        	NSData *fileData = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"HQ_0005.jpg" ofType:nil]];
        	NSData *formData = [NSData q_formDataWithRequest:request 
        	                                            text:@"qian" 
        	                                        textName:@"username" 
        	                                        fileData:fileData 
        	                                            name:@"userfile" 
        	                                        fileName:@"test.jpg" 
        	                                        mimeType:@"imge/jpg"];
        
        	AFURLSessionManager *manager = [[AFURLSessionManager alloc] 
        	                                 initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
        
        	[[manager uploadTaskWithRequest:request fromData:formData progress:^(NSProgress * _Nonnull uploadProgress) {
            
            	float progress = 1.0 * uploadProgress.completedUnitCount / uploadProgress.totalUnitCount;
            	dispatch_async(dispatch_get_main_queue(), ^{
                	[self.progressBtn q_setButtonWithProgress:progress lineWidth:10 lineColor:nil backgroundColor:[UIColor yellowColor]];
            	});
            
        	} completionHandler:^(NSURLResponse * _Nonnull response, id  _Nullable responseObject, NSError * _Nullable error) {
            
            	if (error == nil && responseObject != nil) {
                	NSLog(@"success: %@ --- %@", responseObject, [responseObject class]);
            	} else {
                	NSLog(@"failure: %@", error);
            	}
         	}] resume];
        
      • POST 文件上傳,fileData 形式

        	NSString *urlStr = @"http://192.168.88.200/upload/upload.php";
        
        	NSMutableURLRequest *request = [[AFHTTPRequestSerializer serializer] 
        	                                     multipartFormRequestWithMethod:@"POST" 
        	                                                          URLString:urlStr 
        	                                                         parameters:nil
        	                                          constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
            
            	// 指定文件數據形式上傳
            
            	NSData *fileData = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"HQ_0005.jpg" ofType:nil]];
            	[formData appendPartWithFileData:fileData name:@"userfile" fileName:@"test.jpg" mimeType:@"imge/jpg"];
            	[formData appendPartWithFormData:[@"qian" dataUsingEncoding:NSUTF8StringEncoding] name:@"username"];
            
        	} error: NULL];
        
        	AFURLSessionManager *manager = [[AFURLSessionManager alloc] 
        	                                 initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
        
        	[[manager uploadTaskWithStreamedRequest:request progress:^(NSProgress * _Nonnull uploadProgress) {
            
            	float progress = 1.0 * uploadProgress.completedUnitCount / uploadProgress.totalUnitCount;
            	dispatch_async(dispatch_get_main_queue(), ^{
                	[self.progressBtn q_setButtonWithProgress:progress lineWidth:10 lineColor:nil backgroundColor:[UIColor yellowColor]];
            	});
            
        	} completionHandler:^(NSURLResponse * _Nonnull response, id  _Nullable responseObject, NSError * _Nullable error) {
            
            	if (error == nil && responseObject != nil) {
                	NSLog(@"success: %@ --- %@", responseObject, [responseObject class]);
            	} else {
                	NSLog(@"failure: %@", error);
            	}
        	}] resume];
        
      • POST 文件上傳,fileUrl 形式

        	NSString *urlStr = @"http://192.168.88.200/upload/upload.php";
        
        	NSMutableURLRequest *urlRequest = [[AFHTTPRequestSerializer serializer] 
        	                                        multipartFormRequestWithMethod:@"POST" 
        	                                                             URLString:urlStr 
        	                                                            parameters:nil 
        	                                             constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
            
            	// 指定文件路徑形式上傳
            
            	NSURL *fileUrl = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"HQ_0005" ofType:@"jpg"]];
            	[formData appendPartWithFileURL:fileUrl name:@"userfile" fileName:@"test.png" mimeType:@"image/jpg" error:nil];
            	[formData appendPartWithFormData:[@"qian" dataUsingEncoding:NSUTF8StringEncoding] name:@"username"];
            
        	} error: NULL];
        
        	AFURLSessionManager *manager = [[AFURLSessionManager alloc] 
        	                                 initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
        
        	[[manager uploadTaskWithStreamedRequest:urlRequest progress:^(NSProgress * _Nonnull uploadProgress) {
            
            	float progress = 1.0 * uploadProgress.completedUnitCount / uploadProgress.totalUnitCount;
            	dispatch_async(dispatch_get_main_queue(), ^{
                	[self.progressBtn q_setButtonWithProgress:progress lineWidth:10 lineColor:nil backgroundColor:[UIColor yellowColor]];
            	});
            
        	} completionHandler:^(NSURLResponse * _Nonnull response, id  _Nullable responseObject, NSError * _Nullable error) {
            
            	if (error == nil && responseObject != nil) {
                	NSLog(@"success: %@ --- %@", responseObject, [responseObject class]);
            	} else {
                	NSLog(@"failure: %@", error);
            	}
        	}] resume];
        
      • PUT 文件上傳

        	NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:
        	                                                                            @"http://192.168.88.200/uploads/123.jpg"]];
        	request.HTTPMethod = @"PUT";
        
        	[request setValue:[@"admin:adminpasswd" q_basic64AuthEncode] forHTTPHeaderField:@"Authorization"];
        
        	NSURL *fileURL = [[NSBundle mainBundle] URLForResource:@"HQ_0005.jpg" withExtension:nil];
        
        	AFURLSessionManager *manager = [[AFURLSessionManager alloc] 
        	                                 initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
        	manager.responseSerializer = [AFHTTPResponseSerializer serializer];
        
        	[[manager uploadTaskWithRequest:request fromFile:fileURL progress:^(NSProgress * _Nonnull uploadProgress) {
            
            	float progress = 1.0 * uploadProgress.completedUnitCount / uploadProgress.totalUnitCount;
            	dispatch_async(dispatch_get_main_queue(), ^{
                	[self.progressBtn q_setButtonWithProgress:progress lineWidth:10 lineColor:nil backgroundColor:[UIColor yellowColor]];
            	});
            
        	} completionHandler:^(NSURLResponse * _Nonnull response, id  _Nullable responseObject, NSError * _Nullable error) {
            
            	if (error == nil && responseObject != nil) {
                	NSLog(@"success: %@ --- %@", responseObject, [responseObject class]);
            	} else {
                	NSLog(@"failure: %@", error);
            	}
        	}] resume];
        
    • Download Tasks

      • 普通下載

        	NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://192.168.88.200/download/file/minion_01.mp4"]];
        
        	AFURLSessionManager *manager = [[AFURLSessionManager alloc] 
        	                                 initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
        
        	[[manager downloadTaskWithRequest:request progress:^(NSProgress * _Nonnull downloadProgress) {
            
            	float progress = 1.0 * downloadProgress.completedUnitCount / downloadProgress.totalUnitCount;
            	dispatch_async(dispatch_get_main_queue(), ^{
                	[self.progressBtn q_setButtonWithProgress:progress lineWidth:10 lineColor:nil backgroundColor:[UIColor yellowColor]];
            	});
            
        	} destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {
            
            	return [NSURL fileURLWithPath:[response.suggestedFilename q_appendDocumentPath]];
            
        	} completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {
            
            	if (error == nil) {
                	NSLog(@"success: %@ --- %@", response, [response class]);
            	} else {
                	NSLog(@"failure: %@", error);
            	}
        	}] resume];
        
      • 斷點下載

        	@property (nonatomic, strong) AFURLSessionManager *manager;
        	@property (nonatomic, retain) NSURLSessionDownloadTask *downloadTask;
        
        	@property (nonatomic, strong) NSData   *resumeData;
        	@property (nonatomic, strong) NSString *resumeTmpPath;
        
        	@property (nonatomic, assign) BOOL isDownloading;
        	@property (nonatomic, assign) BOOL isPause;
        
        	- (AFURLSessionManager *)manager {
            	if (_manager == nil) {
                	_manager = [[AFURLSessionManager alloc] 
                	             initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
                	_manager.responseSerializer = [AFHTTPResponseSerializer serializer];
            	}
            	return _manager;
        	}
        
        	- (NSString *)resumeTmpPath {
            	if (_resumeTmpPath == nil) {
                	_resumeTmpPath = [@"resumeTmpData.tmp" q_appendCachePath];
            	}
            	return _resumeTmpPath;
        	}
        
        	// 開始下載
        
        	- (void)start {
            
            	if (self.isDownloading) {
                	NSLog(@"已經開始下載");
                	return;
            	}
            
            	if (self.isPause) {
                
                	NSLog(@"繼續下載");
                
                	[self.downloadTask resume];
                
                	self.isPause = NO;
                	self.isDownloading = YES;
                	return;
            	}
        
            	if (![[NSFileManager defaultManager] fileExistsAtPath:self.resumeTmpPath]) {
            
                	NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:
                	                                                      @"http://120.25.226.186:32812/resources/videos/minion_01.mp4"]];
                
                	self.downloadTask = [self.manager downloadTaskWithRequest:request progress:^(NSProgress * _Nonnull downloadProgress) {
                    
        				[self downloadProgress:downloadProgress];
                    
                	} destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {
                    
        				return [NSURL fileURLWithPath:[response.suggestedFilename q_appendDocumentPath]];
                    
                	} completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {
                    
        				[self downloadCompletion:filePath error:error];
                	}];
                
                	[self.downloadTask resume];
                
                	self.isPause = NO;
                	self.isDownloading = YES;
                
            	} else {
                	[self goon];
            	}
        	}
        
        	// 繼續下載
        
        	- (void)goon {
            
            	if (self.isDownloading) {
                	NSLog(@"已經開始下載");
                	return;
            	}
            
            	if (self.isPause) {
                
                	[self.downloadTask resume];
                	NSLog(@"繼續下載");
                
            	} else {
                
                	self.resumeData = [NSData dataWithContentsOfFile:self.resumeTmpPath];
                
                	self.downloadTask = [self.manager downloadTaskWithResumeData:self.resumeData 
                	                                                    progress:^(NSProgress * _Nonnull downloadProgress) {
                    
        				[self downloadProgress:downloadProgress];
                    
                	} destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {
                    
        				return [NSURL fileURLWithPath:[response.suggestedFilename q_appendDocumentPath]];
                    
                	} completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {
                    
        				[self downloadCompletion:filePath error:error];
                	}];
                	
                	[self.downloadTask resume];
                
                	NSLog(@"繼續下載");
            	}
            
            	self.isPause = NO;
            	self.isDownloading = YES;
        	}
        
        	// 暫停下載
        
        	- (void)pause {
            
            	if (!self.isDownloading) {
                	NSLog(@"已經停止下載");
                	return;
            	}
            
            	[self.downloadTask suspend];
            
            	NSLog(@"暫停下載");
            
            	self.isPause = YES;
            	self.isDownloading = NO;
        	}
        
        	// 停止下載
        
        	- (void)stop {
            
            	if (!self.isDownloading) {
                	NSLog(@"已經停止下載");
                	return;
            	}
            
            	[self.downloadTask cancelByProducingResumeData:^(NSData * _Nullable resumeData) {
                
                	if (resumeData) {
                    
        				self.resumeData = resumeData;
                    
        				[self.resumeData writeToFile:self.resumeTmpPath atomically:YES];
                	}
                
                	self.downloadTask = nil;
                
                	NSLog(@"停止下載");
            	}];
            
            	self.isDownloading = NO;
        	}
        
        	- (void)downloadProgress:(NSProgress *)downloadProgress {
            
            	float progress = 1.0 * downloadProgress.completedUnitCount / downloadProgress.totalUnitCount;
            	dispatch_async(dispatch_get_main_queue(), ^{
        			[self.progressBtn q_setButtonWithProgress:progress lineWidth:10 lineColor:nil 
               	                                                              backgroundColor:[UIColor yellowColor]];
            	});
        	}
        
        	- (void)downloadCompletion:(NSURL *)filePath error:(NSError *)error {
            
            	self.isDownloading = NO;
            
            	if (error == nil) {
                
                	NSLog(@"success: %@", filePath.path);
                
                	[[NSFileManager defaultManager] removeItemAtPath:self.resumeTmpPath error:nil];
                
            	} else {
                
                	NSLog(@"%@", error);
                
                	if (error) {
        				NSLog(@"failure: %@", error.userInfo[NSLocalizedDescriptionKey]);
                    
        				self.resumeData = error.userInfo[NSURLSessionDownloadTaskResumeData];
                	}
                
                	if ([error.localizedFailureReason isEqualToString:@"No such file or directory"]) {
                	
        				[[NSFileManager defaultManager] removeItemAtPath:self.resumeTmpPath error:nil];
                    
        				[self start];
                	}
            	}
        	}
        

9、AFNetworking 單例封裝

  • Objective-C

    • NetworkTools.h

      	#import <AFNetworking/AFNetworking.h>
      
      	@interface NetworkTools : AFHTTPSessionManager
      
      	+ (instancetype)sharedNetworkTools;
      
      	@end
      
    • NetworkTools.m

      	@implementation NetworkTools
      
      	+ (instancetype)sharedNetworkTools {
          	static NetworkTools *tools;
          
          	static dispatch_once_t onceToken;
          	dispatch_once(&onceToken, ^{
              
              	// baseURL 的目的,就是讓后續的網絡訪問直接使用 相對路徑即可,baseURL 的路徑一定要有 / 結尾
              	NSURL *baseURL = [NSURL URLWithString:@"http://c.m.163.com/"];
              
              	NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
              
              	tools = [[self alloc] initWithBaseURL:baseURL sessionConfiguration:config];
              
              	// 修改 解析數據格式 能夠接受的內容類型 - 官方推薦的做法,民間做法:直接修改 AFN 的源代碼
              	tools.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", 
              	                                                                        @"text/json", 
              	                                                                        @"text/javascript", 
              	                                                                        @"text/html", 
              	                                                                        nil];
          	});
          	return tools;
      	}
      
      	@end
      


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM