AFNetworking2.0源碼解析<二>??-- ?構(gòu)建普通請求: 格式化請求參數(shù),生成HTTP Header + 構(gòu)建multipart請求
How to implement a CoreFoundation toll-free bridged NSInputStream subclass
AFNetworking2.0源碼解析<三>??-- ?HTTPS建立過程+CA防止中間人+SSL Pinning
關(guān)于非對稱加密算法的原理:RSA算法原理<一><二>
關(guān)于整個流程:HTTPS那些事<一><二><三>
關(guān)于數(shù)字證書:淺析數(shù)字證書
AFNetworking源碼解析<四>? -- ?AFURLResponseSerialization(2Method+JSON解析+圖片解壓)
AFNetworking 2.0 Migration Guide
AFNetworking 3.0 Migration Guide

AFURLSessionManager
.h? --? NSURLSession + NSOperationQueue,AFURLResponseSerialization + AFSecurityPolicy + AFNetworkReachabilityManager
data/upload/download/Tasks
~~~
.m ?-- ?
隊列2 + 常量 + block
AFURLSessionManagerTaskDelegate
init:(upload/downloadProgress)
setupProgressForTask:? --? 用upload和download的NSProgress = NSURLSessionTask的屬性 + 上傳下載KVO
cleanUpProgressForTask: ?-- ?remove KVO
observeValueForKeyPath:ofObject:change:context: ?-- ?觸發(fā)
URLSession:task:didCompleteWithError: - userInfoDict[ResponseSerializer][AssetPath][ResponseData],(error -- [Error] + 異步主隊列completionHandler + CompleteNotification(userInfoDict) ) +?
responseSerializer(默認JSON解析) + [SerializedResponse][Error] + completionHandler + CompleteNotification(userInfoDict)
URLSession:dataTask:didReceiveData: - appendData
URLSession:downloadTask:didFinishDownloadingToURL: - (FinishDownloadingBlock() -> downloadFileURL) + moveItemAtURL:toURL: + error->FailMoveNotification
static inline void af_swizzleSelector & BOOL af_addMethod ?-- ?methodSwizzling
_AFURLSessionTaskSwizzling
+load - 當前類和父類的resume比較+和原始AFResume比較,↓↓↓
+swizzleResumeAndSuspendMethodForClass:? -- ?MS - af_resume <=> resume & af_suspend <=> suspend
state - StateCanceling
af_resume - [self state] + resume + DidResume通知
af_suspend - [self state] + suspend + DidSuspend通知
AFURLSessionManager
initWithSessionConfiguration:? --? 初始化(session+responseSerializer+securityPolicy+reachabilityManager)
taskDidResume && taskDidSuspend:? --? 通知方法,同一對象發(fā)送的通知->異步主隊列DidSuspend/Resume通知
AFURLSessionManagerTaskDelegate -?getter - [task.taskIdentifier]=delegate
setter ?-- ?setupProgressForTask(delegate初始化) + addNotificationObserverForTask
addDelegateForData/Upload/DownloadTask:upload/downloadProgress:/destination:completionHandler:
- delegate(各種block/FinishDownloadingBlock) -> setForData/Upload/DownloadTask
removeDelegateForTask: - (delegate cleanUp) + remove通知
(tasks + dataTasks + uploadTasks + downloadTasks) - getter -> tasksForKeyPath([self.session getTasksWithCompletionHandler~~])
invalidateSessionCancelingTasks: ?-- ?session2M
dataTaskWithRequest:uploadProgress:downloadProgress:completionHandler: - 安全創(chuàng)建dataTask -> addDelegateForDataTask
uploadTaskWith/StreamedRequest:fromFile/Data:progress:completionHandler: - 安全創(chuàng)建uploadTask (重新創(chuàng)建) -> appDelegateForUploadTask
downloadTaskWithRequest/ResumeData:progress:destination:completionHandler: - 同
各種setBlock(15)
NSURLSessionDelegate
-URLSession:didBecomeInvalidWithError: - BecomeInvalidBlock + notification
-URLSession:didReceiveChallenge:completionHandler: - i. if --驗證挑戰(zhàn)Block ->返回disposition ? else --服務器信任方法-> (securityPolicy)安全評估->證書驗證?
ii. completionBlock(disposition, credential)
NSURLSessionTaskDelegate
-URLSession:task:willPerformHTTPRedirection:newRequest:completionHandler: - HTTP重定向Block + completionBlock
-URLSession:task:didReceiveChallenge:completionHandler: - i. if --驗證挑戰(zhàn)block ->返回disposition ? else --服務器信任方法->安全評估->證書驗證
ii. completionBlock(disposition, credential)
-URLSession:task:needNewBodyStream: - if -- streamBlock -> 返回inputStream ? else -- HTTPBodyStream存在&&實現(xiàn)協(xié)議-> copy ?+ ?completionBlock()
-URLSession:task:didSendBodyData:totalBytesSent:totalBytesExpectedToSend: - 原始請求頭"Content-Length" -> totalUnitCount + DidSendBodyDataBlock()
-URLSession:task:didCompleteWithError: - [delegate URLSession:task:didCompleteWithError:](拼接各種userInfo,通知發(fā)送) + removeDelegate +?taskDidCompleteBlock
NSURLSessionDataDelegate
-URLSession:dataTask:didReceiveResponse:completionHandler: - DidReceiveResponseBlock + completionBlock
-URLSession:dataTask:didBecomeDownloadTask: - remove-dataTask + set-downloadTask +?becomeDownloadTaskBlock()
-URLSession:dataTask:didReceiveData: - delegate的didReceiveData(appendData) + receiveDataBlock()
-URLSession:dataTask:willCacheResponse:completionHandler: - cacheResponseBlock() + completionBlock
-URLSessionDidFinishEventsForBackgroundURLSession: - 異步主隊列(后臺session完成事件block)
NSURLSessionDownloadDelegate
-URLSession:downloadTask:didFinishDownloadingToURL: - (DidFinishDownloadingBlock -> fileURL) + moveItemAtURL:toURL: + FailMoveNotification ?+ ?delegate類似方法(downloadFileURL + FailMoveNotification)
-URLSession:downloadTask:didWriteData:totalBytesWritten:totalBytesExpectedToWrite: - DidWriteDataBlock
-URLSession:downloadTask:didResumeAtOffset:expectedTotalBytes: - DidResumeBlock
NSSecureCoding ?-- ?sessionConfig的編解碼
NSCopying?
AFHTTPSessionManager
.h ?-- ?
.m ?-- ?
initWithBaseURL:sessionConfiguration:? --? url + 請求響應Serializer
Request & ResponseSerializer - setter
GET:parameters:/progress:success:failure: **
HEAD:parameters:success:failure: **
POST:parameters:/progress:success:failure: **
??? POST:parameters:constructingBodyWithBlock:/progress:success:failure: - i. requestSerializer(組裝AFHTTPBodyPart + HTTPBodyStream + HeaderField) + (nil OR failureBlock)?
ii. 父類StreamedRequest:(安全創(chuàng)建uploadTask -> addDelegateForUploadTask)
PUT:parameters:success:failure: **
PATCH:parameters:success:failure: **
DELETE:parameters:success:failure: **
??? dataTaskWithHTTPMethod:URLString:parameters:uploadProgress:
downloadProgress:success:failure: - i. requestSerializer(請求前的配置- (url + HTTPMethod) + (現(xiàn)有ObservedKeyPaths -> [request setValue: forKey:]) + HTTPHeaderField +通過parameters轉(zhuǎn)換為queryString + HTTPMethod做不同設置 ) + (nil OR failureBlock)
ii. ->父類dataTaskWithRequest:(安全創(chuàng)建uploadTask -> addDelegateForUploadTask)
NSSecureCoding? -- ?編解碼5
NSCopying
iOS. PercentEscape是錯用的URLEncode,看看AFN和Facebook吧
蘋果的編碼 != URLEncode
(1)當遇到發(fā)送網(wǎng)絡請求的參數(shù)中有漢字的情況,使用stringByAddingPercentEscapesUsingEncoding:進行轉(zhuǎn)義,這樣帶有漢字的urlString就會將每個漢字轉(zhuǎn)成相應的unicode編碼對應的3個%形式,這叫urlEncode(每個能寫后端的語言都有的方法),但是蘋果的stringByAddingPercentEscapesUsingEncoding:卻不是urlEncode。
&不會轉(zhuǎn)碼 - 產(chǎn)生這種情況的原因是:百分號轉(zhuǎn)義不等于URLEncode,該編碼不同于URL編碼,由于不會對&字符編碼,因此不會改變URL參數(shù)的分隔。URL編碼會編碼&、?與其他標點符號。
(2)iOS 7.0 - stringByAddingPercentEncodingWithAllowedCharacters: 需要傳遞一個參數(shù):這個參數(shù)是一個字符集,表示:在進行轉(zhuǎn)義過程中,不會對這個字符集中包含的字符進行轉(zhuǎn)義,而保持原樣保留下來。
[NSCharacterSet ?letterCharacterSet] 來保證字母不被轉(zhuǎn)義
MORE:遇到queryString中的表單域也需要轉(zhuǎn)義的情況 - person[contact] = 13801001234
[mutableCharSet addCharactersInString:@"[]"];
(3)AFN
GET:@"https://www.baidu.com/s"
parameters:@{@"ie":@"UTF-8",@"wd":@"漢字&ss"};
success:nil ? failure:nil
AFN對queryString的組裝是這樣進行的:
AFN會將parameters傳遞的字典通過將每個表單元素的 field 和 value 進行?urlcode?之后拼接,然后再直接附加在傳遞的URLString后面(當然,如果是POST方式就不是附加了,而是將拼好的串放到HTTP body中)。
(4) AFN URLEncode - 將字典轉(zhuǎn)為queryString的模塊
- 請求前:構(gòu)建request的header和queryString、uploadContent和配置(如超時等),這部分的功能在AFURLRequestSerialization中
- 請求中:分別有基于NSURLConnection的訪問(3.0移除)和基于NSURLSession的訪問模塊
- 請求后:錯誤處理 OR 成功處理:數(shù)據(jù)格式轉(zhuǎn)換和解析,主要在AFURLResponseSerialization中
NSArray* AFQueryStringPairsFromKeyAndValue(NSString*key, id value);
<1> 利用AFQueryStringPairsFromKeyAndValue函數(shù)將parameters字典中的每個key-value對取出,將每個key-value對構(gòu)建為AFQueryStringPair對象,放到一個數(shù)組中。
<2> 在AFQueryStringFromParameters方法內(nèi)部遍歷這個數(shù)組(每個元素為AFQueryStringPair對象),使用AFQueryStringPair類的轉(zhuǎn)義方法?URLEncodedStringValue 將 AFQueryStringPair 轉(zhuǎn)為字符串,將這些字符串存入新的數(shù)組中。這樣新數(shù)組中的每個元素就是轉(zhuǎn)義之后的field=value字符串,最后用&將數(shù)組元素連接即可。
NSString* AFPercentEscapedStringFromString(NSString*string)
(5)queryString轉(zhuǎn)為字典的需求
Facebook的facebook-ios-sdk
+ (NSDictionary*)dictionaryWithQueryString:(NSString*)queryString;?
+ (NSString*)URLDecode:(NSString*)value;
AFURLRequestSerialization
.h? --??
AFPercentEscapedStringFromString() + AFQueryStringFromParameters()
@protocol - requestBySerializingRequest:withParameters:error:
AFHTTPRequestSerializer
+serializer
- HTTPHeaderField setter & getter
- AuthorizationHeaderField
- requestWithMethod:URLString:parameters:error:
multipartFormRequestWithMethod:URLString:parameters:constructingBodyWithBlock:error:
- requestWithMultipartFormRequest:writingStreamContentsToFile:completionHandler:
@protocol AFMultipartFormData - 7
AFJSONRequestSerializer
AFPropertyListRequestSerializer
.m ?-- ?
AFPercentEscapedStringFromString - allowCharacterSet中移除編碼字符+ stringByAddingPercentEncodingWithAllowedCharacters
AFQueryStringPair
- initWithField:value:
- URLEncodedStringValue -> AFPercentEscapedStringFromString(NSString *string) = habit%5B%5D=%E6%B8%B8%E6%B3%B3
通過parameters轉(zhuǎn)換為queryString AFQueryStringFromParameters(URLEncodedStringValue) -> AFQueryStringPairsFromDictionary -> AFQueryStringPairsFromKeyAndValue(組裝NSArray,內(nèi)部是AFQueryStringPair對象)
AFHTTPRequestSerializerObservedKeyPaths - 單例ObservedKeyPaths = @[allowsCellularAccess, cachePolicy, HTTPShouldHandleCookies/UsePipelining, networkServiceType, timeoutInterval]
AFHTTPRequestSerializer
-init ?- ?"Accept-Language"/User-Agent HeaderField + HTTP Method + 觀察ObservedKeyPaths中屬性
allowsCellularAccess/cachePolicy/HTTPShouldHandleCookies/UsePipelining/networkServiceType/timeoutInterval 手動觸發(fā)KVO
HTTPRequestHeaders setter & getter
-setAuthorizationHeaderFieldWithUsername:password: - NSData(NSString) -> NSString(NSData base64) -> setHTTPRequestHeaders
- requestWithMethod:URLString:parameters:error: - (url + HTTPMethod)? + 現(xiàn)有ObservedKeyPaths -> [request setValue: forKey:] + (HTTPHeaderField +通過parameters轉(zhuǎn)換為queryString + HTTPMethod做不同設置)
-multipartFormRequestWithMethod:URLString:parameters:constructingBodyWithBlock:error:
AFStreamingMultipartFormData + (pair.value -> data +組裝AFHTTPBodyPart) + block,first&last設置YES + HTTPBodyStream + Content-Type/-Length HeaderField
-requestWithMultipartFormRequest:writingStreamContentsToFile:completionHandler: - ioStream - (read:maxLength: & write:maxLength:)
-requestBySerializingRequest:withParameters:error: - HTTPHeaderField +通過parameters轉(zhuǎn)換為queryString + HTTPMethod做不同設置
NSKeyValueObserving - 在ObservedKeyPaths中手動調(diào)用 + 收到KVO,非NSNull->add
NSSecureCoding - mutableHTTPRequestHeaders & queryStringSerializationStyle的編解碼
NSCopying
AFCreateMultipartFormBoundary - @"Boundary+%08X%08X"
AFMultipartFormInitial/Encapsulation/FinalBoundary - ~~
AFContentTypeForPathExtension - 通過pathExtension返回contentType
AFHTTPBodyPart
-init -> transitionToNextPhase - - (runloop&open + close)
-inputStream - 根據(jù)body類型設置_inputStream(set是.body=~, get是.inputStream)
-stringForHeaders - headers的(key: value/r/n ~~~)組成的string
-contentLength - AFHTTPBodyPart的contentLength = (2BoundaryData+headersData+_bodyContentLength)
-hasBytesAvailable - 根據(jù)streamStatus返回是否可用
-read:maxLength: - _phase->(2BoundaryData+HeaderData) -> ↓↓↓
-readData:intoBuffer:maxLength: - [data getBytes:buffer range:range] + _phaseReadOffset + NextPhaseIfNeed
NSCopying
AFMultipartBodyStream
-initWithStringEncoding:
-setInitialAndFinalBoundaries - first&last設置YES
-read:maxLength: - [HTTPBodyPart read:maxLength:]
-open - (statusOpen + boundaryYES + Enumerator)
NSCopying - 內(nèi)部AFHTTPBodyPart copy + BoundaryYES
AFStreamingMultipartFormData
-initWithURLRequest:stringEncoding:
-appendPartWithFileURL:name:error: - fileName+mimeType -> ↓↓↓
-appendPartWithFileURL:name:fileName:mimeType:error: - (不是fileURL ||返回是否URL's資源存在且可達) -> error(userInfo) ?+ ?拼接AFHTTPBodyPart(Headers=(key:Content-Disposition/-Type value:~)+length=fileAttributes[NSFileSize])
-appendPartWithInputStream:name:fileName:length:mimeType: - 拼接AFHTTPBodyPart(Headers=(key:Content-Disposition/-Type value:~)
-appendPartWithFileData:name:fileName:mimeType:(2Headers+data) -> **
-appendPartWithFormData:name:(Headers+data) -> appendPartWithHeaders:body:(組裝AFHTTPBodyPart) - **
-requestByFinalizingMultipartFormData? - first&last設置YES + HTTPBodyStream + Content-Type/-Length HeaderField
AFJSONRequestSerializer
-requestBySerializingRequest:withParameters:error: - @"GET", @"HEAD", @"DELETE"其中之一-> [super ~~] ?OR ?(HTTPRequestHeaders -> mutableRequestHeaders) + (hasParameters -> JSON頭+HTTPBody:JSON數(shù)據(jù))
NSSecureCoding - writingOptions的編解碼
NSCopying
AFPropertyListRequestSerializer
-requestBySerializingRequest:withParameters:error: - @"GET", @"HEAD", @"DELETE"其中之一-> [super ~~] ?OR??(HTTPRequestHeaders -> mutableRequestHeaders) + (hasParameters -> x-plist頭+HTTPBody:PList數(shù)據(jù))
NSSecureCoding - format&writeOptions的編解碼
NSCopying
AFURLResponseSerialization
.h ?-- ?
@protocol - responseObjectForResponse:data:error:
AFHTTPResponseSerializer
+serializer?
-validateResponse:data:error:? --? 驗證響應是否有效
AFJSONResponseSerializer
+serializerWithReadingOptions:
AFXMLParserResponseSerializer
AFPropertyListResponseSerializer
+serializerWithFormat:readOptions:
AFImageResponseSerializer
AFCompoundResponseSerializer
+compoundSerializerWithResponseSerializers:
.m ?-- ?
AFErrorWithUnderlyingError
AFErrorOrUnderlyingErrorHasCodeInDomain
AFJSONObjectByRemovingKeysWithNullValues - 遞歸
AFHTTPResponseSerializer
NSSecureCoding - acceptableStatusCodes & acceptableContentTypes的編解碼
NSCopying
AFJSONResponseSerializer
-init - @"application/json",@"text/json",@"text/javascript"
-responseObjectForResponse:data:error: - 響應有效性 + (length > 0 && 非空格=>解析) + 去(key - value:(nil OR NSNull)) + 返回
NSSecureCoding - readingOptions & removesKeysWithNullValues的編解碼
NSCopying
AFXMLParserResponseSerializer
-init - @"application/xml",@"text/xml"
-responseObjectForResponse:data:error: - 響應有效性 + NSXMLParserWithData
AFPropertyListResponseSerializer
-init - @"application/x-plist"
-responseObjectForResponse:data:error: - 響應有效性 + data ->解析 + 返回
NSSecureCoding - format & readOptions的編解碼
NSCopying
UIImage (AFNetworkingSafeImageLoading)
+af_safeImageWithData - 單例鎖+鎖imageWithData
AFImageWithDataAtScale - 安全初始化 + 動圖返回 + 初始化withScale
AFInflatedImageFromResponseWithDataAtScale - 解碼圖片
AFImageResponseSerializer
-init - @"image/tiff ~~~"
-responseObjectForResponse:data:error: - 響應有效性 + AFInflatedImageFromResponseWithDataAtScale解碼圖片 OR AFImageWithDataAtScale創(chuàng)建
NSSecureCoding - imageScale & automaticallyInflatesResponseImage的編解碼
NSCopying
AFCompoundResponseSerializer
-responseObjectForResponse:data:error: - 遍歷驗證響應 OR 返回super
NSSecureCoding - responseSerializers的編解碼
NSCopying
AFSecurityPolicy - 封裝了證書驗證的過程
.h ?-- ?系統(tǒng)信任CA機構(gòu)列表驗證 + SSL Pinning
+certificatesInBundle:
+defaultPolicy
+policyWithPinningMode:withPinnedCertificates:
-evaluateServerTrust:forDomain:
.m ?-- ?
AFSecKeyIsEqualToKey - isEqual:
AFPublicKeyForCertificate - certificateData->PublicKey
AFServerTrustIsValid - SecTrustEvaluate -> Unspecified && Proceed
AFCertificateTrustChainForServerTrust - 遍歷serverTrust的SecCertificateRef —>拿Data - [trustChain add:certificateData]
AFPublicKeyTrustChainForServerTrust - 遍歷serverTrust的(SecCertificateRef+policy+SecTrustRef) -> (trust+&result) -> [trustChain add:copy(publicKey)]
AFSecurityPolicy
+certificatesInBundle: - (本地.cer - [certificatesSet add:certificateData])
+defaultPinnedCertificates - 單例 + ↑↑↑
+defaultPolicy - 驗證域名+ None
+policyWithPinningMode:withPinnedCertificates: - SSLPinningMode + ↓↓↓
+setPinnedCertificates: - 由本地的pinnedCertificates(cerNSData) -> AFPublicKeyForCertificate() = pinnedPublicKeys
-evaluateServerTrust:forDomain: - if + (驗證域名=SSL->SecTrustSetPolicies) + ~ + Certificate -> (本地或外設pinnedCertificates(cerData)->SecCertificateCreateWithData()->MArray=AnchorCers AND AFServerTrustIsValid()->= serverTrust(CertificateData))??
PublicKey -> serverTrust的cer對應的publicKeys AND 本地pinnedPublicKey =有一個相等
NSSecureCoding - SSLPinningMode&allowInvalidCertificates&validatesDomainName&pinnedCertificates的編解碼
copyWithZone
AFNetworkReachabilityManager
.h ?-- ?
+manager
+managerForDomain/Address:
-initWithReachability:
-startMonitoring / stopMonitoring
.m ?-- ?
AFStringFromNetworkReachabilityStatus - 網(wǎng)絡status返回description
AFNetworkReachabilityStatusForFlags - SCNetworkFlags各種& -> AFNetworkStatus
AFPostReachabilityStatusChange - flags->status +異步主隊列(block +通知(userInfo:status))
AFNetworkReachabilityManager
+sharedManager: - +manager(address)->managerForAddress:
+managerForDomain: - domain->reachability->manager
+managerForAddress: - address->reachability->manager
+manager: - address -> ↑↑↑
-initWithReachability: - 網(wǎng)絡可達&狀態(tài)
-startMonitoring: - callback(設置status +回調(diào)StatusBlock(status)) -> (context -> setCallback(Callback) -> runloop)
異步后臺SCNetworkGetFlags->AFPostStatusChange(status->post通知)
-stopMonitoring: - SCNetworkReachabilityUnscheduleFromRunLoop()
-keyPathsForValuesAffectingValueForKey: - 當reachable+reachableViaWWAN+reachableViaWiFi發(fā)生變化,被認為networkReachabilityStatus發(fā)生變化,發(fā)出通知
AFAutoPurgingImageCache
.h -- ?
@protocol - AFImageCache
-addImage:withIdentifier:
removeImageWithIdentifier:
removeAllImages:
imageWithIdentifier:
@protocol - AFImageRequestCache
addImage:forRequest:withAdditionalIdentifier:
removeImageforRequest:withAdditionalIdentifier:
imageforRequest:withAdditionalIdentifier:
AFAutoPurgingImageCache
initWithMemoryCapacity:preferredMemoryCapacity:
.m ?-- ?
AFCachedImage = Model
initWithImage:identifier:
AFAutoPurgingImageCache - cachedImagesDict
initWithMemoryCapacity:preferredMemoryCapacity: - 初始化+并發(fā)隊列+內(nèi)存警告removeAll通知
addImage:withIdentifier: - i. 阻塞異步i.并發(fā)隊列-判斷previous+(cachedImages+currentMemoryUsage)Add? ii. 自動清除最早時間圖片-拿cachedImagesDict的所有values(images)按lastAccessDate排序-> remove +減少currentMemoryUsage
removeImageWithIdentifier/AllImages: - 阻塞同步并發(fā)隊列- removeObjectForKey/AllObjects
imageCacheKeyFromURLRequest:withAdditionalIdentifier: - request.URL.absoluteString
AFImageDownloader??
--? NSURLCache + AFAutoPurgingImageCache
.h ?-- ?
AFImageDownloadReceipt
AFImageDownloader
initWithSessionManager:downloadPrioritization:maximumActiveDownloads:imageCache:
-downloadImageForURLRequest:/withReceiptID:success:failure:
-cancelTaskForImageDownloadReceipt:
.m ?-- ?
AFImageDownloaderResponseHandler - uuid + successBlock + failureBlock
-initWithUUID:success:failure:
AFImageDownloaderMergedTask - URLIdentifier + identifier + task +responseHandlersArray
-initWithURLIdentifier:identifier:task:
AFImageDownloadReceipt - task + receiptID
-initWithReceiptID:task:
AFImageDownloader
+defaultURLCache(內(nèi)存緩存20M + 磁盤緩存150M)
+defaultURLSessionConfiguration(各種配置+defaultURLCache)
-init(defaultConfiguration + AFImageResponseSerializer ->> sessionManager + AFAutoPurgingImageCache) ---------> initWithSessionManager:downloadPrioritization:maximumActiveDownloads:imageCache - 各種+串行&并發(fā)隊列
+defaultInstance - init
↑↑↑URLCache -> SessionConfig -> SessionManager -> AFImageDownloader
-downloadImageForURLRequest:withReceiptID:success:failure: - 同步串行( 1.取現(xiàn)存的mergedTask,拼接responseHandler -> add,return task?
2. 如果緩存策略允許,嘗試從圖片緩存加載圖片,!=nil & success ->異步主隊列回調(diào)??
3. 通過AFHTTPSessionManager創(chuàng)建dataTask) ?--> 異步并發(fā)隊列(成功 -> 同步串行removeMergedTask,error - 遍歷mergedTask.responseHandlersArray(異步主隊列回調(diào)所有handler.failureBlock),noError -緩存圖片 + 遍歷(異步主隊列回調(diào)所有hander.successBlock)
同步串行ActiveTaskCount-- ?+ ?同步串行-出隊列==suspend -> resume)
4. 獲得createdTask,拼接handler->拼接mergedTask(add拼接handler) -> mergedTasks[key:URLIdentifier value:mergedTask]
5. 開始mergedTask OR入隊mergedTask --- return task
6. return拼接receipt
-cancelTaskForImageDownloadReceipt
同步串行(1. 拿mergedTask.responseHandlers中是否有uudi==imageDownloadReceipt.receiptID?
2. Found -> remove +拼接error(userInfo) ->異步主隊列回調(diào)failureBlock)
3. 收尾檢查,handlers==0 & state == suspend -> taskCancel + removeFromMergedTask
-enqueueMergedTask: - 出隊列是firstObject,F(xiàn)IFO -加后面,LIFO -加前面
-dequeueMergedTask - 數(shù)組當隊列,firstObj + removeObj
AFNetworkActivityIndicatorManager ?-- ?任務數(shù)控制?活動器
.h ?-- ?
各種set + update - 4
- increment/decrementActivityCount - 賦值(手動調(diào)用KVO) +更新
.m ?-- ?
-init - resume/suspend/completeNotification對應方法 -> +-ActivityCount
+sharedManager - init = resume/suspend/completeNotification - 通知方法: networkRequestDidStart&networkRequestDidFinish -- ↓↓↓
-incrementActivityCount & -decrementActivityCount - 賦值(手動調(diào)用KVO) +更新
-setEnabled: - =NO -> StateNotActive
-setCurrentState: -?NotActive(cancel2+關(guān)閉) + DelayingStart(+1s回調(diào)Active&NotActive) + Active(cancel1+打開) + DelayingEnd(+0.17回調(diào)NotActive)
-updateCurrentStateForNetworkActivityChange: - NotActive(未激活&&有活動=延遲開始) + Active(激活&&沒有活動=延遲結(jié)束) + DelayingEnd(延遲結(jié)束&&有活動=激活)
-startActivationDelayTimer: + activationDelayTimerFired - (定時器1s -> runloop) => (活動數(shù)>0 - setState:Active - NotActive) + 活動數(shù)>0 - setState:Active - NotActive
-startCompletionDelayTimer: + completionDelayTimerFired - (定時器0.17s -> runloop) => (setState:NotActive) + completion == NotActive
-setNetworkActivityIndicatorVisible: - 賦值(手動調(diào)用KVO) + 更新(IndicatorVisible)
UIButton+AFNetworking ?--? 緩存+下載
.h ?-- ?
- setImageForState:withURLRequest:placeholderImage:success:failure:
- setBackgroundImageForState:withURLRequest:placeholderImage:success:failure:
.m ?-- ?
UIButton (_AFNetworking)
af_imageDownloadReceipt -?關(guān)聯(lián)對象 getter & setter(key是各種state)
af_setBackgroundImageDownloadReceipt - 關(guān)聯(lián)對象 getter & setter(key是各種state)
UIButton (AFNetworking)
ImageDownloader- 關(guān)聯(lián)對象 getter & setter
- setImageForState:withURLRequest:placeholderImage:success:failure: -- ?緩存+下載
- setBackgroundImageForState:withURLRequest:placeholderImage:success:failure: ? ? ? ? ?-- ?緩存+下載?
UIImageView+AFNetworking? --? 緩存+下載
.h ?-- ?
- setImageWithURLRequest:placeholderImage:success:failure:
.m ?-- ?
UIImageView (_AFNetworking)
af_activeImageDownloadReceipt - 關(guān)聯(lián)對象 getter & setter
UIImageView (AFNetworking)
sharedImageDownloader - 關(guān)聯(lián)對象 getter & setter
- cancelImageDownloadTask -> cancelTaskForImageDownloadReceipt:(ImageDownloader)
- setImageWithURLRequest:placeholderImage:success:failure: ?-- ?緩存+下載
UIProgressView+AFNetworking ?-- ?根據(jù)task數(shù)據(jù)做相應progress
.h ?-- ?
-setProgressWithUpload/DownloadProgressOfTask:animated:
.m ?--
af_uploadProgressAnimated & af_downloadProgressAnimated關(guān)聯(lián)對象
-setProgressWithUploadProgressOfTask:animated:? --? (KVO task的"state""countOfBytesSent"屬性) + af_setUploadProgressAnimated(保存動畫BOOL)
-setProgressWithDownloadProgressOfTask:animated:? --? (KVO task的"state""countOfBytesReceived"屬性) + af_setDownloadProgressAnimated(保存動畫BOOL)
-observeValueForKeyPath:ofObject:change:context:? --? (context -> keyPath) -> 異步主隊列 - set:比例 animated:af_uploadProgressAnimated? OR? 異步主隊列 - set:比例animated:af_downloadProgressAnimated? OR? 完成態(tài)state -> removeStateObserver + context(對應observer)
UIActivityIndicatorView+AFNetworking -- 任務狀態(tài)開始結(jié)束動畫
.h ?--
- setAnimatingWithStateOfTask:
.m ?--
UIActivityIndicatorView (AFNetworking) - 持有Observer對象
-af_notificationObserver - notificationObserver懶加載
-setAnimatingWithStateOfTask:? --? af_notificationObserver~~
AFActivityIndicatorViewNotificationObserver
-initWithActivityIndicatorView:
-setAnimatingWithStateOfTask:? --? (=running->start? OR? stop)? + 通知 - 對應方法↓↓
-af_startAnimating? --? 異步主隊列startAnimating
-af_stopAnimating? --? 異步主隊列stopAnimating
UIRefreshControl+AFNetworking
.h ?--?
-setRefreshingWithStateOfTask:
.m ?-- ?
UIRefreshControl (AFNetworking)?- 持有Observer對象
-af_notificationObserver - notificationObserver懶加載
-setAnimatingWithStateOfTask:? --? af_notificationObserver~~
AFActivityIndicatorViewNotificationObserver
-initWithActivityIndicatorView:
-setRefreshingWithStateOfTask:? --? (=running->start? OR? stop)? + 通知 - 對應方法↓↓
-af_beginRefreshing? --? 異步主隊列beginRefreshing
-af_endRefreshing? --? 異步主隊列endRefreshing
UIWebView+AFNetworking
.h ?-- ?
- loadRequest:progress:success:failure: - ↓↓↓ success: (響應的textEncodingName -> CFStringEncoding -> NSStringEncoding) + (有success前向回調(diào)successBlock(response, HTMLString) )
- loadRequest:MIMEType:textEncodingName:progress:success:failure: - (running || suspend -> cancel)?+ dataTask = (success一直前向回調(diào)successBlock + (系統(tǒng)方法loadData + delegate方法) + error一直前向回調(diào)failureBlock) + *progress = (taskIdentifier對應delegate.downloadProgress)
.m ?--
UIWebView (_AFNetworking)
af_URLSessionTask關(guān)聯(lián)對象
UIWebView (AFNetworking)
-sessionManager ?-- ?return 關(guān)聯(lián)對象 OR 單例
sessionManager關(guān)聯(lián)對象
-responseSerializer? --? return 關(guān)聯(lián)對象 OR 單例
responseSerializer關(guān)聯(lián)對象