iOS網路請求框架:MKNetWorkKit的使用
2014-07-11
MKNetWorkKit是由一個印度小夥子寫的,是用於網路請求的庫,支援ARC,程式碼的網址這裡給出。
作者原始碼地址(MugunthKumar):MKNetworkKit
作者類庫介紹中文翻譯地址(翻譯作者,csdn博主kmyhy,楊巨集焱):csdn博主kmyhy
這裡面大多數時候會引用到它裡面的demo,MKNetWorkKit-iOS-Demo,本文主要是根據作者原文以及作者的demo還有自己的使用寫的文章。
在整個程式中只有一個全域性佇列 MKNetWorkKit中主要有兩個類,MKNetworkEngine和MKNetworkOperation,MKNetworkOperation就是一個操作,是NSOperation的子類,每個HTTP操作通過MKNetworkEngine入隊,佇列是一個NSOperationQueue,在程式是一個單例,在MKNetworkEngine的initialize裡建立。
GET請求 一般自己會複寫MKNetworkEngine,在這裡提供一個每一個網路請求的介面,可以傳入引數,請求完成和失敗的block。
self.yahooEngine = [[YahooEngine alloc] initWithHostName:@"download.finance.yahoo.com"];
YahooEngine的GET請求方法的申明
typedef void (^CurrencyResponseBlock)(double rate);
-(MKNetworkOperation*) currencyRateFor:(NSString*) sourceCurrency
inCurrency:(NSString*) targetCurrency
completionHandler:(CurrencyResponseBlock) completion
GET請求方法的實現
-(MKNetworkOperation*) currencyRateFor:(NSString*) sourceCurrency
inCurrency:(NSString*) targetCurrency
completionHandler:(CurrencyResponseBlock) completionBlock
errorHandler:(MKNKErrorBlock) errorBlock {
MKNetworkOperation *op = [self operationWithPath:YAHOO_URL(sourceCurrency, targetCurrency)
params:nil
httpMethod:@"GET"];
[op addCompletionHandler:^(MKNetworkOperation *completedOperation)
{
// the completionBlock will be called twice.
// if you are interested only in new values, move that code within the else block
NSString *valueString = [[completedOperation responseString] componentsSeparatedByString:@","][1];
DLog(@"%@", valueString);
if([completedOperation isCachedResponse]) {
DLog(@"Data from cache %@", [completedOperation responseString]);
}
else {
DLog(@"Data from server %@", [completedOperation responseString]);
}
completionBlock([valueString doubleValue]);
}errorHandler:^(MKNetworkOperation *errorOp, NSError* error) {
errorBlock(error);
}];
[self enqueueOperation:op];
return op;
}
GET請求方法的呼叫
self.currencyOperation = [ApplicationDelegate.yahooEngine currencyRateFor:@"SGD"
inCurrency:@"USD"
completionHandler:^(double rate) {
[[[UIAlertView alloc] initWithTitle:@"Today's Singapore Dollar Rates"
message:[NSString stringWithFormat:@"%.2f", rate]
delegate:nil
cancelButtonTitle:NSLocalizedString(@"Dismiss", @"")
otherButtonTitles:nil] show];
}
errorHandler:^(NSError* error) {
DLog(@"%@\t%@\t%@\t%@", [error localizedDescription], [error localizedFailureReason],
[error localizedRecoveryOptions], [error localizedRecoverySuggestion]);
}];
POST請求,上傳一張圖片
-(MKNetworkOperation*) uploadImageFromFile:(NSString*) file
completionHandler:(IDBlock) completionBlock
errorHandler:(MKNKErrorBlock) errorBlock {
MKNetworkOperation *op = [self operationWithPath:@"upload.php"
params:@{@"Submit": @"YES"}
httpMethod:@"POST"];
[op addFile:file forKey:@"image"];
// setFreezable uploads your images after connection is restored!
[op setFreezable:YES];
[op addCompletionHandler:^(MKNetworkOperation* completedOperation) {
NSString *xmlString = [completedOperation responseString];
DLog(@"%@", xmlString);
completionBlock(xmlString);
}
errorHandler:^(MKNetworkOperation *errorOp, NSError* error) {
errorBlock(error);
}];
[self enqueueOperation:op];
return op;
}
上傳的時候可以增加一個進度條,所以在呼叫這個方法的時候可以有以下程式碼。
NSString *uploadPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingFormat:@"/SampleImage.jpg"];
self.uploadOperation = [ApplicationDelegate.testsEngine uploadImageFromFile:uploadPath
completionHandler:^(id twitPicURL) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Uploaded to"
message:(NSString*) twitPicURL
delegate:nil
cancelButtonTitle:NSLocalizedString(@"Dismiss", @"")
otherButtonTitles:nil];
[alert show];
self.uploadProgessBar.progress = 0.0;
}
errorHandler:^(NSError* error) {
[UIAlertView showWithError:error];
}];
[self.uploadOperation onUploadProgressChanged:^(double progress) {
DLog(@"%.2f", progress*100.0);
self.uploadProgessBar.progress = progress;
}];
正確顯示網路狀態指示
正確顯示網路狀態指示的判斷條件就是操作operation數大於0的時候。
自動改變佇列大小 在wifi以及3G網路是會呼叫setMaxConcurrentOperationCount:方法切換最大運算元的大小。
自動快取 MKNetWorkKit能夠快取你所有的GET請求,當請求相同時會呼叫本地快取內容。
[self.yahooEngine useCache];
清空快取使用如下方法
[ApplicationDelegate.yahooEngine emptyCache];
凍結網路操作 網路斷開時的網路請求會被凍結,通過NSKeyedArchiver序列化在本地,當有網時會再次請求。MKNetworkOperation的setFreezable:方法就是凍結操作。
[op setFreezable:YES];
類似的請求只請求一個操作
就是同一個URL只請求一次。
圖片快取 MKNetworkEngine的imageAtURL:completionHandler:errorHandler:方法能夠快取圖片。
[ApplicationDelegate.apiEngine imageAtURL:[NSURL URLWithString:(_strategyModel
.titlepic)] completionHandler:^(UIImage* fetchedImage, NSURL* url, BOOL isInCache){
[iv setImage:fetchedImage];
}errorHandler:nil];
當然MKNetworkEngine的operationWithURLString: params: httpMethod:方法也可以請求圖片,並且快取,它其實就是根據一個URL地址來建立一個網路執行緒,然後把它加入到佇列就可以了。
MKNetworkOperation *op1 =[ApplicationDelegate.apiEngine operationWithURLString:_strategyModel.titlepic params:nil httpMethod:nil];
[op1 addCompletionHandler:^(MKNetworkOperation *completedOperation) {
// [op1 responseImage];
[iv setImage:[completedOperation responseImage]];
} errorHandler:^(MKNetworkOperation *errorOp, NSError* error) {
}];
[ApplicationDelegate.apiEngine enqueueOperation:op1];
其實MKNetworkOperation有各種response資料,這裡是responseImage,還有responseString、responseJSON、responseXML。
不過請求一個圖片還可以使用MK提供的category,UIImageView+MKNetworkKitAdditions裡面的方法,如下,不過我試了之後好像沒有快取,不過這個可以用於tableview上每個cell上顯示的圖片,比上面的要方便許多。
[self.thumbnailImage setImageFromURL:[NSURL URLWithString:self.loadingImageURLString]
placeHolderImage:nil];
快取operation 其實每一個get請求都有快取,要想知道你返回的資料是否快取,可以用以下方法。
[op addCompletionHandler:^(MKNetworkOperation *completedOperation)
{
// the completionBlock will be called twice.
// if you are interested only in new values, move that code within the else block
if([completedOperation isCachedResponse]) {
DLog(@"Data from cache %@", [completedOperation responseString]);
}
else {
DLog(@"Data from server %@", [completedOperation responseString]);
}
completionBlock([valueString doubleValue]);
}errorHandler:^(MKNetworkOperation *errorOp, NSError* error) {
errorBlock(error);
}];
下載檔案 下載檔案的時候也可以增加進度條,方法類似上面上傳檔案的使用,下載檔案痛喲在操作上增加一個一個輸出流,下載檔案的實現可以如下。
-(MKNetworkOperation*) downloadFatAssFileFrom:(NSString*) remoteURL toFile:(NSString*) filePath {
MKNetworkOperation *op = [self operationWithURLString:remoteURL];
[op addDownloadStream:[NSOutputStream outputStreamToFileAtPath:filePath
append:YES]];
[self enqueueOperation:op];
return op;
}