2012-10-30 44 views
6

我是新來MKNetworkKit,但我已經能夠將其添加到我的項目,這是完全與可達性變化打交道時,除了工作。MKNetworkKit操作不恢復/完成時可達改變

這裏的情況是:

  1. 我禁用WiFi和運行應用程序。
  2. 即使沒有可達性,我要求由我MKNetworkEngine子類創建MKNetworkOperation(使用POST)的一些數據。在請求數據之前,操作被設置爲可凍結(根據Mugunth Kumar's doc)。
  3. MKNetworkEngine啓用WiFi,checkAndRestoreFrozenOperations之後被調用,它檢測有一個掛起的操作(不可達性創建的),它試圖排隊。
  4. 在那之後,我的onCompletion塊永遠不會被調用。

有什麼我不懂凍結操作+可達MKNetworkKit?凍結僅適用於請求啓動後可訪問性發生變化的操作嗎?或者我應該實現我自己的可達性改變塊?

這裏是我的MKNetworkEngine子類,創建操作並開始請求的代碼。請注意,不相關的代碼已被抑制。

NSMutableDictionary *params = [NSMutableDictionary dictionaryWithObject:@"value" forKey:@"param"]; 
MKNetworkOperation *op = [self operationWithPath:MYPATH 
              params:params 
             httpMethod:@"POST"]; 
[op setFreezable:YES]; 

[op onCompletion:^(MKNetworkOperation *completedOperation) { 
    // ... 
    // Here is where I process response and send the result to my completion block 
    // It's called when WiFi is available, but not called otherwise. 
    // ... 
} onError:^(NSError *error) { 
    // It's called when WiFi is available, but not called otherwise. 
    DLog(@"Some error"); 
}]; 

[self enqueueOperation:op]; 

return op; 
+0

你設立一臺主機引擎?如果您查看凍結操作的處理方式,除非爲引擎定義了主機,否則它們不起作用。 –

+0

@KenWoo是的。我的引擎子類中的init方法調用'[super initWithHostName:]'。 – msoler

+0

@msoler你有沒有得到它的工作?我有類似的問題 – alandalusi

回答

6

這是兩個不同的問題:恢復與完整。

  1. 簡歷:的凍結/解凍機制只有在啓用緩存

    必須在您的AppDelegate -didFinishLaunchingWithOptions調用-useCache工作:

    self.networkEngine = [[MKNetworkEngine alloc] init ...]; 
    [self.networkEngine useCache]; // <- Add this line 
    
  2. 完整:完成回調是而不是在網絡狀態改變時調用(即在Unfreeze之後)

    然而,如果你採取行動(1),並放置一個斷點在MKNetworkOperation.m -checkAndRestoreFrozenOperations在行:

    [self enqueueOperation:pendingOperation] 
    

    你會發現,它被調用網絡連接恢復時,那pendingOperation你待職位。但是,由於新的MKNetworkOperation已經被實例化(並且此時完成塊可能不再存在),因此您的onCompletion塊永遠不會被調用。一種可能的解決方法是使用通知而不是回叫。

  3. 完整修復:比(2)更穩健的方法可以在啓動時使用,可以用NSNotifications替換^{}塊回調。儘早註冊您的聽衆,就像在您的AppDelegate中一樣。以下是使MKNetworkKit通知變得精明所需的最小變化:

    3a。在MKNetworkOperation.h

    插入通知常數
    #define MKNetworkOperationCompletionNotification @"MKNetworkOperationCompletionNotification" 
    #define MKNetworkOperationErrorNotification @"MKNetworkOperationErrorNotification" 
    

    3B。廣播在MKNetworkOperation.m -operationSucceeded成功通知(請注意,我用postNotificationOnMainThread使得所述通知可以從主線程聽取和更改UI;見NSOperation and NSNotificationCenter on the main thread):

    -(void) operationSucceeded { 
        NSDictionary * aUserInfo = [NSDictionary dictionaryWithObjectsAndKeys: 
         self, NSStringFromClass([MKNetworkOperation class]), 
         nil]; 
        NSNotification * notification = [NSNotification notificationWithName:MKNetworkOperationCompletionNotification 
         object:nil 
         userInfo:aUserInfo]; 
        [[NSNotificationCenter defaultCenter] postNotificationOnMainThread:notification]; 
        ... 
    

    3C。廣播在MKNetworkOperation.m -operationFailedWithError

    -(void) operationFailedWithError:(NSError*) error { 
        self.error = error; 
        NSDictionary * aUserInfo = [NSDictionary dictionaryWithObjectsAndKeys: 
         self, NSStringFromClass([MKNetworkOperation class]), 
         error, NSStringFromClass([NSError class]), 
         nil]; 
        NSNotification * notification = [NSNotification notificationWithName:MKNetworkOperationErrorNotification 
         object:nil 
         userInfo:aUserInfo]; 
    
        [[NSNotificationCenter defaultCenter] postNotificationOnMainThread:notification]; 
        ... 
    

    3D失敗通知。註冊一個相當持久化對象,像AppDelegate中,作爲一個聽衆(不要忘記註銷):

    // Listen to POST changes 
        NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter]; 
        [defaultCenter addObserver:self 
         selector:@selector(mkNetworkOperationCompletionNotification:) 
         name:MKNetworkOperationCompletionNotification 
         object:nil]; 
        [defaultCenter addObserver:self 
         selector:@selector(mkNetworkOperationErrorNotification:) 
         name:MKNetworkOperationErrorNotification 
         object:nil]; 
    

    3E。的聽衆可能是什麼樣子示例代碼:

    - (void)mkNetworkOperationCompletionNotification:(NSNotification*)notification { 
        MKNetworkOperation *operation = [[notification userInfo] 
         objectForKey:NSStringFromClass([MKNetworkOperation class])]; 
        NSLog(@"operationSucceeded: %@", [operation responseString]); 
    } 
    
    - (void)mkNetworkOperationErrorNotification:(NSNotification*)notification { 
        NSError * error = [[notification userInfo] objectForKey:NSStringFromClass([NSError class])]; 
        NSLog(@"operationFailedWithError: %@", [error localizedDescription]); 
    } 
    

做到這一點,你就大功告成了。十

編輯,以去除在前面的回答不必要的建議修改MKNetworkOperation.h,並添加第3款,以顯示如何克服^ {}限制。

+1

非常感謝您的詳細解答,@ gothicdev。 – msoler