一个iOS 框架介绍:MKNetworkKit
2019獨(dú)角獸企業(yè)重金招聘Python工程師標(biāo)準(zhǔn)>>>
ASIHTTPRequest (作者:BenCopsey) 是一個(gè)使用簡(jiǎn)單,可用于各種從簡(jiǎn)單到復(fù)雜的 HTTP 請(qǐng)求,或者可用于處理 Amazon S3、Rackspace 等REST 服務(wù)的強(qiáng)大框架。
不幸的是,Ben 早在 2011 年 9 月 21 日就已經(jīng)聲明停止開發(fā)和支持該框架(見http://allseeing-i.com/%5Brequest_release%5D; )。
Ben 推薦了許多可替代的框架(比如AFNetworking, RestKit 或 LRResty)。但最有潛力的莫過(guò)于Mugunth Kumar 的 MKNetworkKit 。Mugunth 曾發(fā)布了許多高質(zhì)量的開源的 iOS/Mac 代碼(比如 MKStoreKit),其中值得推薦一個(gè)就是 ASHTTPRequest 的替代者: MKNetworkKit。它支持 ARC 和塊,易于使用且極為高效。
以下內(nèi)容摘自 Mugunth自己的博客。原文位于:http://blog.mugunthkumar.com/products/ios-framework-introducing-mknetworkkit。
?
假設(shè)有一個(gè)網(wǎng)絡(luò)框架,它能自動(dòng)為你緩存 respones,能在你離線時(shí)自動(dòng)記憶你的操作,你覺得怎樣?
當(dāng)你離線時(shí),你可以收藏某個(gè) tweet 頁(yè)或者標(biāo)記某個(gè) feed 為已讀,當(dāng)你再次上線時(shí),網(wǎng)絡(luò)框架會(huì)自動(dòng)執(zhí)行你的這些操作,這一切都不需要你額外編寫代碼。請(qǐng)看我對(duì)于MKNetworkKit 框架的介紹。
?
什么是MKNetworkKit?
MKNetworkKit是一個(gè) O-C 編寫的網(wǎng)絡(luò)框架,支持塊,ARC 且用法簡(jiǎn)單。
MKNetworkKit 集 ASIHTTPRequest 和 AFNetworking 兩個(gè)框架于一體。在集成二者的優(yōu)秀特性之外,還增加了一堆新的功能。尤其是,相比起其它框架,它能讓你更輕松地編寫代碼。它讓你徹底遠(yuǎn)離那些惡心的網(wǎng)絡(luò)代碼。
特點(diǎn)
超輕量級(jí)框架
整個(gè)框架只有 2 個(gè)類和一些類別方法。因此,它的使用極其簡(jiǎn)單。
在整個(gè)程序中只有一個(gè)全局隊(duì)列
高度依賴互聯(lián)網(wǎng)連接的 app 應(yīng)該優(yōu)先考慮網(wǎng)絡(luò)線程的并發(fā)數(shù)。不幸的是,沒有任何網(wǎng)絡(luò)框架在這方面做得夠好。因此,一旦你在程序中沒有控制好網(wǎng)絡(luò)線程的并發(fā)數(shù),就極易導(dǎo)致出錯(cuò)。
假設(shè)你要上傳一堆圖片到服務(wù)器上。絕大多數(shù)移動(dòng)網(wǎng)絡(luò)(3G)不會(huì)允許你對(duì)同一個(gè)IP 地址的 HTTP 并發(fā)連接數(shù)超過(guò) 2 個(gè)。換句話說(shuō),在設(shè)備上,你不能從 3G 網(wǎng)絡(luò)中獲得 2 個(gè)以上的 HTTP 并發(fā)連接。對(duì)于 Edge 則更糟,大多數(shù)情況不能超過(guò)1 個(gè)。相比較家用寬帶網(wǎng)絡(luò)(Wifi),則這個(gè)限制要寬得多(6 個(gè))。但是,你不可能總是使用 wifi,你必須也考慮到有限網(wǎng)絡(luò)(窄帶)的連通性。更多的時(shí)候,iDevice設(shè)備幾乎都能連接到 3G 網(wǎng)絡(luò),因此,你同時(shí)只能上傳 2 張圖片。但是,真正的問(wèn)題不是緩慢的上傳速度,而是另一種情況。在你打開一個(gè) view 試圖加載縮略圖(不同的view)時(shí),上傳線程被運(yùn)行到后臺(tái)。如果你沒有控制好上傳隊(duì)列中的線程數(shù),你的縮略圖會(huì)加載超時(shí)。這是不正常的。正確的方式是優(yōu)化縮略圖加載線程,或者讓線程等待直到上傳完成再加載縮略圖。這需要你在整個(gè)程序中只擁有一個(gè)queue 隊(duì)列。
MKNetworkKit 在它的每個(gè)實(shí)例中使用單例來(lái)保證這一點(diǎn)。并不是說(shuō)MKNetworkKit 是單例的,而是說(shuō)它的共享隊(duì)列是單例的。
正確顯示網(wǎng)絡(luò)狀態(tài)指示
許多第 3 方框架都通過(guò)一個(gè)“網(wǎng)絡(luò)連接數(shù)增加/減少”的方法回調(diào)來(lái)顯示網(wǎng)絡(luò)狀態(tài),MKNetworkKit則由于使用了單例的共享隊(duì)列,能自動(dòng)顯示網(wǎng)絡(luò)狀態(tài)。在共享隊(duì)列中有一個(gè)線程通過(guò) KVO 方式會(huì)隨時(shí)觀察 operationCount 屬性。因此對(duì)于開發(fā)者,一般情況下根本不需要操心網(wǎng)絡(luò)狀態(tài)的顯示。
if?(object?==?_sharedNetworkQueue?&&?[keyPath isEqualToString:@"operationCount"])?{ ??? ?[UIApplication sharedApplication].networkActivityIndicatorVisible?=?????????([_sharedNetworkQueue.operations count]?<?0); ?????} |
自動(dòng)改變隊(duì)列大小
如前所述,絕大部分移動(dòng)網(wǎng)絡(luò)不允許 2 個(gè)以上的并發(fā)連接,因此你的隊(duì)列大小在3G 網(wǎng)絡(luò)下應(yīng)當(dāng)設(shè)置為 2。 MKNetworkKit 會(huì)自動(dòng)為你處理好這個(gè)。當(dāng)網(wǎng)絡(luò)出于3G/EDGE/GPRS 時(shí),它會(huì)將并發(fā)數(shù)調(diào)整到 2。當(dāng)網(wǎng)絡(luò)處于 Wifi 網(wǎng)絡(luò)時(shí),則自動(dòng)調(diào)整到 6。當(dāng)你通過(guò) 3G 網(wǎng)絡(luò)中從遠(yuǎn)程服務(wù)器加載縮略圖時(shí),這種調(diào)整能帶來(lái)極大的好處。
自動(dòng)緩存
MKNetworkKit 能自動(dòng)緩存你所有的 GET 請(qǐng)求。當(dāng)你再次發(fā)起同樣的請(qǐng)求時(shí),MKNetworkKit?隨即就能調(diào)用 response緩存(如果可用的話)傳遞給 handler 進(jìn)行處理。當(dāng)然,它同時(shí)也向服務(wù)器發(fā)出請(qǐng)求。一旦獲得服務(wù)器數(shù)據(jù),handler 被再次要求處理新獲取的數(shù)據(jù)。也就是說(shuō),你不用手動(dòng)緩存。你只需要使用:
?[[MKNetworkEngine sharedEngine]?useCache]; |
當(dāng)然,你可以覆蓋這個(gè)方法(子類化),定制你的緩存路徑和緩存占用的內(nèi)存開銷。
凍結(jié)網(wǎng)絡(luò)操作
MKNetworkKit 能夠“凍結(jié)”網(wǎng)絡(luò)操作。在一個(gè)網(wǎng)絡(luò)操作被“凍結(jié)”的情況下,一旦網(wǎng)絡(luò)連斷開,它們將自動(dòng)序列化并在設(shè)備再次連線時(shí)自動(dòng)被提交一次。類似 twitter 客戶端的“drafts”。
當(dāng)你提交一篇 tweet 時(shí),如果網(wǎng)絡(luò)被標(biāo)記為“可凍結(jié)”,MKNetworkKit 會(huì)自動(dòng)執(zhí)行凍結(jié)并儲(chǔ)存這些請(qǐng)求。因此會(huì)在將來(lái)推遲發(fā)送這篇 tweet。整個(gè)過(guò)程不需要你寫一行代碼。這個(gè)特性你可以用于其他操作,諸如收藏一篇 tweet 或者從 Goolge reader 客戶端共享一個(gè)帖子,加一個(gè)鏈接到Instapaper 中,等等。
類似的請(qǐng)求只執(zhí)行一個(gè)操作
當(dāng)你加載縮略圖(針對(duì) twitter stream)時(shí),你最終得為每個(gè)實(shí)際的圖片創(chuàng)建一個(gè)新的請(qǐng)求。實(shí)際上你所進(jìn)行的多個(gè)請(qǐng)求都是同一個(gè)URL。MKNetworkKit 對(duì)于隊(duì)列中的每個(gè) GET 請(qǐng)求都只會(huì)執(zhí)行一次。它還不能到緩存 POST 請(qǐng)求。
圖片緩存
MKNetworkKit 內(nèi)置了縮略圖緩存。只要覆蓋幾個(gè)方法,就可以設(shè)置內(nèi)存中最大能緩存的圖片數(shù)量,以及緩存要保存到目錄。當(dāng)然,你也可以不覆蓋這些方法。
性能
即速度。MKNetworkKit 緩存是內(nèi)置的,就如 NSCache,當(dāng)發(fā)現(xiàn)有內(nèi)存警告,緩存到內(nèi)存中的數(shù)據(jù)將被寫入緩存目錄。
完全支持 ARC
一般你只會(huì)在新項(xiàng)目中使用新的網(wǎng)絡(luò)框架。MKNetworkKit并不意味著要放棄已有的框架(當(dāng)然你也可以放棄,這會(huì)是個(gè)乏味的工作)。對(duì)于新的項(xiàng)目,你總是想使用 ARC。當(dāng)你看到本文的時(shí)候,很可能 MKNetworkKit ?會(huì)是僅有的完全支持 ARC 的網(wǎng)絡(luò)框架。ARC 通常比非 ARC 代碼更快。
用法
Ok,我就不“自賣自夸”了。讓我們立即了解如果使用這個(gè)框架。
添加MKNetworkKit
將 MKNetworkKit 目錄拖到項(xiàng)目中
添加下列框架: CFNetwork.Framework, SystemConfiguration.framework, Security.framework and ImageIO.Framework.
將 MKNetworkKit.h 頭文件包含到 PCH 文件中
對(duì)于 iOS,刪除 NSAlert+MKNetworkKitAdditions.h
對(duì)于 Mac,刪除 UIAlertView+MKNetworkKitAdditions.h
總共只需要 5 個(gè)核心文件,真是一個(gè)強(qiáng)大的網(wǎng)絡(luò)開發(fā)包
MKNetworkKit 的類
MKNetworkOperation
MKNetworkEngine
一些工具類 (Apple 的 Reachability) 以及類別
我喜歡簡(jiǎn)單。蘋果已經(jīng)寫了最基本最核心的網(wǎng)絡(luò)代碼。第 3 方框架需要的是提供一個(gè)優(yōu)雅的網(wǎng)絡(luò)隊(duì)列最多再加上緩存。我認(rèn)為第3 方框架不應(yīng)該超過(guò) 10 個(gè)類(無(wú)論它是網(wǎng)絡(luò)的還是 UIKit 還是別的什么)。超過(guò)這個(gè)數(shù)就太臃腫了。Three20 就是一個(gè)例子。現(xiàn)在 ShareKit 又是這樣。盡管它們是優(yōu)秀的,但仍然是龐大和臃腫的。ASIHttpRequest or AFNetworking 比 RESTKit 更輕,JSONKit比TouchJSON (或者任何 TouchCode 庫(kù))更輕。這只是我自己的看法,但當(dāng)一個(gè)第三方庫(kù)的代碼超過(guò)程序源代碼1/3,我就不會(huì)使用它。
框架臃腫帶來(lái)的問(wèn)題是很難理解它的內(nèi)部工作機(jī)制,以及很難根據(jù)自己的需求定制它(當(dāng)你需要時(shí))。我曾經(jīng)寫過(guò)的一些框架(例如MKStoreKit ,用于應(yīng)用程序內(nèi)購(gòu)的 )總是易于使用,我認(rèn)為MKNetworkKit 也應(yīng)該是這樣。對(duì)于 MKNetworkKit ,你所需要了解的就是暴露在兩個(gè)類MKNetworkOperation 和 MKNetworkEngine 中的方法。MKNetworkOperation 就好比ASIHttpRequest類。它是一個(gè)NSOperation 子類,封裝了你的 request 和 response 類。對(duì)于每個(gè)網(wǎng)絡(luò)操作,你需要?jiǎng)?chuàng)建一個(gè)MKNetworkOperation 。
MKNetworkEngine 是一個(gè)偽單例類,管理程序中的網(wǎng)絡(luò)隊(duì)列。它是偽單例的,也就是說(shuō),對(duì)于簡(jiǎn)單請(qǐng)求,你可以直接用MKNetworkEngine 中的方法。要進(jìn)行深度的定制,你應(yīng)該進(jìn)行子類化。每個(gè) MKNetworkEngine 子類有它自己的Reachability 對(duì)象,用于通知它來(lái)自服務(wù)器的reachability 通知。對(duì)于不同的 REST 服務(wù)器,你可以考慮創(chuàng)建單獨(dú)的 MKNetworkEngine子類。
它是偽單例,它的子類的每個(gè)請(qǐng)求都共用唯一的一個(gè)隊(duì)列。你可以在應(yīng)用程序委托中retain 這個(gè) MKNetworkEngine ,就像CoreData 的 managedObjectContext 類一樣。在使用MKNetworkKit 時(shí),創(chuàng)建一個(gè) MKNetworkEngine 子類將你的網(wǎng)絡(luò)請(qǐng)求進(jìn)行邏輯上的分組。例如,將所有關(guān)于 Yahoo 的方法放在一個(gè)類,所有 Facebook 有關(guān)的方法放進(jìn)另一個(gè)類。來(lái)看 3 個(gè)實(shí)際使用的例子。
例1:
創(chuàng)建一個(gè) ?“YahooEngine” 從 Yahoo 財(cái)經(jīng)服務(wù)器抓取貨幣匯率。
步驟 1:創(chuàng)建YahooEngine 類繼承于MKNetworkEngine。MKNetworkEngine 使用主機(jī)名和指定的頭(如果有的話)進(jìn)行初始化。頭信息可以是nil。如果你是在自己的 REST 服務(wù)器上,你可以考慮加一個(gè)客戶端 app 的版本或者其他信息(比如客戶端的標(biāo)識(shí))。
NSMutableDictionary?*headerFields?=?[NSMutableDictionary?dictionary];?????[headerFields setValue:@"iOS"forKey:@"x-client-identifier"]; self.engine?=?[[YahooEngine alloc]?initWithHostName:@"download.finance.yahoo.com"??????????????????????? customHeaderFields:headerFields]; |
?
注意,yahoo 并不識(shí)別你在頭中發(fā)送x-client-identifier 給它,這個(gè)示例僅僅是演示這個(gè)特性而
由于使用了 ARC 代碼,作為開發(fā)者你需要擁有(強(qiáng)引用)Engine對(duì)象。
一旦你創(chuàng)建了一個(gè) MKNetworkEngine子類, Reachability 即自動(dòng)實(shí)現(xiàn)。當(dāng)你的服務(wù)器由于某些情況掛了,主機(jī)名不可訪問(wèn),你的請(qǐng)求會(huì)自動(dòng)被凍結(jié)。關(guān)于“凍結(jié)”,請(qǐng)參考后面的“凍結(jié)操作”小節(jié)。
步驟 2:設(shè)計(jì)Engine 類 (關(guān)注分離)
現(xiàn)在,開始編寫 Yahoo Engine 中的方法,以抓取匯率。這些方法將在ViewController 中被調(diào)用。良好的設(shè)計(jì)體驗(yàn)是確保不要將 engine 類中的 URL/HTTPHeaders 暴露給調(diào)用者。你的視圖不應(yīng)該知道URL 或者相關(guān)的參數(shù)。也就是,只需要向 engine 方法傳遞貨幣種類和貨幣單位就可以了。方法的返回值可能是 double,即匯率,以及獲取匯率的時(shí)間。由于是異步操作,你應(yīng)當(dāng)在塊中返回這些值。例如:
-(MKNetworkOperation*)?currencyRateFor:(NSString*)?sourceCurrency??????????????????? ??????? ??? inCurrency:(NSString*)?targetCurrency ??? ??????? onCompletion:(CurrencyResponseBlock)?completion ? ??????onError:(ErrorBlock)?error; |
在父類 MKNetworkEngine 中,定義了3 個(gè)塊類型:
typedef?void?(^ProgressBlock)(double?progress); typedef?void?(^ResponseBlock)(MKNetworkOperation*?operation); typedef?void?(^ErrorBlock)(NSError*?error); |
在 YahooEngine中,我們使用了一個(gè)新的塊類型:CurrencyResponseBlock,用以返回匯率。其定義如下:
typedef?void?(^CurrencyResponseBlock)(double?rate); |
在其他正式的 app 中,你應(yīng)該定義自己的塊類似于CurrencyResponseBlock ,用以向 ViewController 返回?cái)?shù)據(jù)。
步驟 3:處理數(shù)據(jù)
處理數(shù)據(jù),包括將從服務(wù)器抓來(lái)的數(shù)據(jù)(例如 JSON/XML/plists)進(jìn)行數(shù)據(jù)類型轉(zhuǎn)換。這應(yīng)當(dāng)在 Engine 中完成。注意,不要在控制器中完成。你的 Engine 應(yīng)當(dāng)將數(shù)據(jù)以適當(dāng)?shù)哪P蛯?duì)象或模型對(duì)象的數(shù)組返回。在engine 中轉(zhuǎn)換 JSON/XML 為模型——注意,適當(dāng)保持關(guān)注分離,view controller 不應(yīng)當(dāng)知道任何用于訪問(wèn) JSON 節(jié)點(diǎn)的 key。這種思想主導(dǎo)了engine 的設(shè)計(jì)。許多網(wǎng)絡(luò)框架并不強(qiáng)制要求你服從關(guān)注分離,我們這樣做,是因?yàn)槲覀優(yōu)槟憧紤]到了。
步驟 4:實(shí)現(xiàn)方法
現(xiàn)在,我們來(lái)討論方法實(shí)現(xiàn)細(xì)節(jié)。要從 Yahoo 獲得匯率信息,最簡(jiǎn)單的是發(fā)起一個(gè) GET 請(qǐng)求。下列宏用一對(duì)指定的貨幣格式化 URL 字串:
We will now discuss the implementationdetails of the method that calculates your currency exchange.
Getting currency information from Yahoo,is as simple as making a GET request.
I wrote a macro to format this URL for a given currency pair.
#define YAHOO_URL(__C1__, __C2__) [NSString stringWithFormat:@"d/quotes.csv?e=.csv&f=sl1d1t1&s=%@%@=X", __C1__, __C2__] |
按如下順序編寫 engine類方法:
根據(jù)參數(shù)準(zhǔn)備 URL
創(chuàng)建一個(gè) MKNetworkOperation 對(duì)象
設(shè)置方法參數(shù)
設(shè)置 operation 的 completion 塊和 error 塊(在 completation 塊中處理 response 并轉(zhuǎn)換為模型)
可選地,添加一個(gè) progress 塊(或者在 view controller 中做這個(gè))
如果 operation 是下載,設(shè)置下載流(通常是文件)。這步也是可選的
當(dāng) operation 完成,處理結(jié)果并調(diào)用方法塊,并將數(shù)據(jù)返回給調(diào)用者。
示例代碼如下:
MKNetworkOperation *op = [selfoperationWithPath:YAHOO_URL(sourceCurrency, targetCurrency)
params:nil
httpMethod:@"GET"];
?
??? [op onCompletion:^(MKNetworkOperation*completedOperation)
???? {
????????DLog(@"%@", [completedOperation responseString]);
?
?//do your processing here
?? ??????completionBlock(5.0f);
?
???? }onError:^(NSError* error) {
?
?? ??????errorBlock(error);
???? }];
?
??? [self enqueueOperation:op];
?
??? return op;
上述代碼格式化 URL 并創(chuàng)建了 MKNetworkOperation。設(shè)置完 completion 和 error 塊之后,將 operation 加入到隊(duì)列(通過(guò)父類的?enqueueOperation 方法),然后返回一個(gè) operation 的引用。因此,如果你在 viewDidAppear 中調(diào)用這個(gè)方法,則在 viewWillDisappear 方法中取消operation。取消 operation 將釋放 operation 以便執(zhí)行 queue 中用于其他view 的 operation(牢記,在移動(dòng)網(wǎng)絡(luò)中只有2 個(gè) operation 能被同時(shí)進(jìn)行,當(dāng) operation 不再需要時(shí)取消它們能提升 app 的性能和速度)。
在 viewcontroller 中也可以添加一個(gè) progress 塊用以刷新UI。例如:
[self.uploadOperation onUploadProgressChanged:^(double?progress)?{??? ????? DLog(@"%.2f", progress*100.0);???????? ????? ????? self.uploadProgessBar.progress?=?progress;??? ?}]; |
MKNetworkEngine 也有一個(gè)只用 URL 創(chuàng)建 operation 的有用方法。因此第1行代碼也可以寫成:
MKNetworkOperation?*op?=?[self operationWithPath:YAHOO_URL(sourceCurrency, targetCurrency)]; |
注意,請(qǐng)求的 URL將自動(dòng)添加上主機(jī)名(在 engine 實(shí)例化時(shí)指定的)。
?
像這樣的實(shí)用方法 MKNetworkEngine還有許多,你可以查看頭文件。
例2:
上傳圖片到服務(wù)器 (例如 TwitPic)。
現(xiàn)在讓我們看一個(gè)上傳圖片到服務(wù)器的例子。要上傳圖片,顯然要 operation 能編碼 multi-part 表單數(shù)據(jù)。 MKNetworkKit 使用類似 ASIHttpRequest 的方式。
你可以非常簡(jiǎn)單地通過(guò)MKNetworkOperation 的 addFile:forKey:方法將一個(gè)文件作為請(qǐng)求中的 multi-part 表單數(shù)據(jù)提交。
MKNetworkOperation 也有一個(gè)方法,可以將圖片以 NSData 的方式提交。即 addData:forKey:?方法,它可以將圖片以NSData 的方法上傳到服務(wù)器。 (例如直接從相機(jī)中捕獲的圖片).
例3:
下載文件到本地目錄 (緩存)
使用MKNetworkKit 從服務(wù)器下載文件并保存到 iPhone 的本地目錄非常簡(jiǎn)單。
只需要設(shè)置 MKNetworkOperation的 outputStream 。
[operation setDownloadStream:[NSOutputStream???????? outputStreamToFileAtPath:@"/Users/mugunth/Desktop/DownloadedFile.pdf"?????????????????????? ??append:YES]]; |
你可以設(shè)置多個(gè) outputStream 到一個(gè) operation,將同一文件保存到幾個(gè)地方(例如其中一個(gè)是你的緩存目錄,另一個(gè)用做你的工作目錄)。
例4:
緩存圖片的縮略圖
對(duì)于下載圖片,你可能需要提供一個(gè)絕對(duì) URL 地址而不是一個(gè)路徑。
MKNetworkEngine 的operationWithURLString:params:httpMethod: 方法根據(jù)絕對(duì) URL地址來(lái)創(chuàng)建網(wǎng)絡(luò)線程。
MKNetworkEngine 相當(dāng)聰明。它會(huì)將同一個(gè) URL 的多次 GET 請(qǐng)求合并成一個(gè),當(dāng) operation 完成時(shí)它會(huì)通知所有的塊。這顯著提升了抓取圖片 URL 以渲染縮略圖的速度.
子類化 MKNetworkEngine然后覆蓋圖片的緩存目錄及緩存的大小。如果你不想定制這二者,你可以直接調(diào)用 MKNetworkEngine中的方法來(lái)下載圖片。這是我極力推薦的。
緩存operation
MKNetworkKit 默認(rèn)會(huì)緩存所有請(qǐng)求。你所需要的僅僅是在你自己的 engine 中打開它。當(dāng)執(zhí)行一個(gè) GET 請(qǐng)求時(shí),如果上次的 response 已緩存,相應(yīng)的 completion 塊將用緩存的response 進(jìn)行調(diào)用(瞬間)。要想知道 response 是否緩存,可以調(diào)用 isCachedResponse 方法,如下所示:
[op onCompletion:^(MKNetworkOperation?*completedOperation)?{ ??????? ??if([completedOperation isCachedResponse])?{ ??????? ??????DLog(@"Data from cache"); ??????????}else?{ ??????? ??????DLog(@"Data from server"); ??????????} ????? ??????DLog(@"%@",?[completedOperation responseString]); ? ????} onError:^(NSError*?error)?{ ????? ??????errorBlock(error); }]; |
凍結(jié)operation
MKNetworkKit 的一個(gè)最有趣的特性是它內(nèi)置的凍結(jié) operation 特性。你只需要設(shè)置 operation 的 freeesable 屬性就可以。幾乎什么也不用做!
[op setFreezable:YES]; |
凍結(jié)是指 operation 在網(wǎng)絡(luò)被斷開時(shí)自動(dòng)序列化并在網(wǎng)絡(luò)恢復(fù)后自動(dòng)執(zhí)行。例如當(dāng)你離線時(shí)也能夠進(jìn)行收藏tweet 的操作,然后在你再次上線時(shí) operation 自動(dòng)恢復(fù)執(zhí)行。
在應(yīng)用程序進(jìn)入后臺(tái)時(shí),凍結(jié)的 operation 也會(huì)被持久化到磁盤。然后在應(yīng)用程序回到前臺(tái)后自動(dòng)恢復(fù)執(zhí)行。
MKNetworkOperation 中的有用方法
如下所示,MKNetworkOperation 公開了一些有用的方法,你可從中獲取各種格式的 response 數(shù)據(jù):
responseData
responseString
responseJSON (Only on iOS 5)
responseImage
responseXML
error
當(dāng) operation 執(zhí)行完時(shí),這些方法被用于獲取響應(yīng)數(shù)據(jù)。如果格式不正確,方法會(huì)返回nil。例如,響應(yīng)的數(shù)據(jù)明明是一個(gè) HTML 格式,你用 responseImage 方法只會(huì)得到 nil。只有 responseData 能保證無(wú)論什么格式都返回正確,而其他方法你必須確保和相應(yīng)的repsone 類型匹配。
有用的宏
DLog 和 ALog 宏被無(wú)恥地從 Stackoverflow 剽竊來(lái)了,我找不到源作者。如果是你寫的,請(qǐng)告訴我。
關(guān)于GCD 的一點(diǎn)說(shuō)明
因?yàn)榫W(wǎng)絡(luò)線程有可能會(huì)能被停止或優(yōu)先處理,我果斷放棄了 GCD——GCD 的效率是比NSOperation 高,但它做不到這一點(diǎn)。我建議在你的網(wǎng)絡(luò)線程中也不要使用基于 GCD 的隊(duì)列。
轉(zhuǎn)載于:https://my.oschina.net/u/1984662/blog/291112
總結(jié)
以上是生活随笔為你收集整理的一个iOS 框架介绍:MKNetworkKit的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 几个优化 Cacti 监控服务性能的技巧
- 下一篇: .net 引用Com组件的几种方案