2015-02-07 33 views
0

我做了一個連接到ReactiveCocoa中的按鈕的登錄。即使我測試了這段代碼,它似乎工作正常,我不知道如果我做對了。 登錄信號在成功時返回「下一個」,在其他情況下返回「錯誤」。由於我不想讓Button在發生錯誤時取消訂閱,因此我使用catch函數。Reactive Cocoa中的超時實現是否正確?

我想要什麼:如果loginSignal沒有被觸發,我想在2秒後觸發超時。這是否正確完成?這種做法是否也適用於「被動方式」?

[[[[self.loginButton rac_signalForControlEvents:UIControlEventTouchUpInside] 
     doNext:^(id x) { 
      [self disableUI]; 
     }] 
     flattenMap:^(id value) { 
      return [[[[[self.login loginSignalWithUsername:self.usernameTextField.text 
               andPassword:self.passwordTextField.text] 
        catch:^RACSignal *(NSError *error) { 
         [self enableUI]; 
         [self showAlertWithTitle:NSLocalizedString(@"ERROR_TITLE", @"Error") 
             message:NSLocalizedString(@"LOGIN_FAILURE", @"Login not successful.")]; 
         return [RACSignal empty]; 
        }] 

        deliverOn:[RACScheduler mainThreadScheduler]] 
        timeout:2.0 onScheduler:[RACScheduler mainThreadScheduler]] 
        catch:^RACSignal *(NSError *error) { 
         [self enableUI]; 
         [self showAlertWithTitle:NSLocalizedString(@"TIMEOUT_TITLE", @"Timeout occured") 
             message:NSLocalizedString(@"REQUEST_NOT_POSSIBLE", @"Server request failed")]; 
         return [RACSignal empty]; 
        }]; 
     }] 
     subscribeNext:^(id x) { 
      [self enableUI]; 
      // Go to next page after login 
     }]; 

回答

2

你應該在我看來,使用RACCommand這是對UI結合信號一個很好的樞紐:

RACCommand* command = [[RACCommand alloc] initWithSignalBlock:^(id _) { 
    return [[[self.login loginSignalWithUsername:self.username password:self.password] 
      doCompleted:^{ 
       // move to next screen 
      }] 
      timeout:2.0 onScheduler:[RACScheduler mainThreadScheduler]]; 
}]; 
self.button.rac_command = command; 

然後,您可以處理使用命令「錯誤」的錯誤(登錄或者超時)信號:

[[command errors] subscribeNext:^(NSError* err) { 
    // display error "err" to the user 
}]; 

該信號在執行時會自動禁用該按鈕。如果您需要禁用UI的其他部分,則可以使用該命令的「正在執行」信號。

[[command executing] subscribeNext:^(NSNumber* executing) { 
    if([executing boolValue]) { 
     [self disableUI]; 
    } else { 
     [self enableUI]; 
    } 
}]; 

// bonus note: if your enableUI method took a BOOL you could lift it in one line : 
[self rac_liftSelector:@selector(enableUI:) withSignals:[command executing], nil]; 

here is a blog article talking about RACCommands

+0

這看上去很好!謝謝!還有一個問題:現在看起來超時定義了,什麼時候我會得到任何答案。如何在完成信號到達後立即得到信號?如果我在那段時間沒有得到任何答案,超時應該只會觸發。 – beseder 2015-02-12 09:17:28

+0

我從來沒有使用超時,但看着代碼它似乎並沒有延遲原來的完整信號。你有更多關於你的登錄信號的細節嗎? – kamidude 2015-02-12 09:25:54

+0

我在loginSignal內部的錯誤處理了'sendNext:',因爲我在過去使用錯誤時遇到了取消訂閱的問題。現在我在任何錯誤上使用'sendError:',現在它就像一個魅力!非常感謝!! – beseder 2015-02-14 10:00:48

相關問題