2012-10-30 17 views
6

を変更したときに、私はMKNetworkKitに新たなんだけど、私は自分のプロジェクトに追加することができましたし、それは完全に到達可能性の変化を扱うときを除いて取り組んでいます。ここでMKNetworkKit操作が完了/再開しません到達可能性が

は状況です:

  1. 私は無線LANを無効にして、アプリを実行します。
  2. 私はMKNetworkEngineサブクラスからMKNetworkOperationを作成して、到達可能性がなくても(POSTを使用して)リクエストします。データを要求する直前に、操作はフリーズ可能(Mugunth Kumar's doc)です。
  3. のWiFiを有効にした後、MKNetworkEnginecheckAndRestoreFrozenOperationsが呼び出され、それがエンキューしようとする1つの保留中の操作(到達可能性なしで作成したもの)は、ある検出します。その後
  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

これは、再開と完了の2つの問題です。

  1. 履歴書:凍結/凍結解除メカニズムはキャッシュのみが

    を有効になっている場合は、あなたのAppDelegateの-didFinishLaunchingWithOptionsに-useCacheを起動する必要があります動作します:

    self.networkEngine = [[MKNetworkEngine alloc] init ...]; 
    [self.networkEngine useCache]; // <- Add this line 
    
  2. 完全:完了コールバックは、ネットワークステータスの変更時に呼び出されないである(つまり、凍結解除後)

    しかし、あなたはラインで-checkAndRestoreFrozenOperationsをアクション(1)に乗り、MKNetworkOperation.mにブレークポイントを配置する場合:

    [self enqueueOperation:pendingOperation] 
    

    あなたはネットワーク接続が復元されたとき、それが呼び出されることがわかり、そのうpendingOperation保留中のPOSTです。ただし、新しいMKNetworkOperationがインスタンス化されているため(完了ブロックが存在しなくなると)、onCompletionブロックが呼び出されることはありません。 1つの回避策は、コールバックの代わりに通知を使用することです。

  3. 完全な修正:より堅牢なアプローチ(2)よりも起動渡って動作しますNSNotificationsによって^{}ブロックコールバックを交換することです。あなたのAppDelegateのように早くリスナーを登録してください。以下は、MKNetworkKitの通知をわかりやすくするために必要な最小限の変更です:

    3a MKNetworkOperation.h

    挿入通知定数
    #define MKNetworkOperationCompletionNotification @"MKNetworkOperationCompletionNotification" 
    #define MKNetworkOperationErrorNotification @"MKNetworkOperationErrorNotification" 
    

    図3b。放送MKNetworkOperation.m -operationSucceededで成功通知(私は通知がメインスレッドからに耳を傾け、UIを変更することができると述べているpostNotificationOnMainThreadを使用することに注意してください。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を追加する編集。)X.

+1

詳細な回答、@ gothicdevに感謝します。 – msoler

関連する問題