2015-02-07 5 views
0

Я сделал логин, который подключен к кнопке в ReactiveCocoa. Даже я протестировал этот кусок кода, и, похоже, он работает правильно, я не уверен, правильно ли я это сделаю. Сигнал входа в систему возвращает «следующий» в случае успеха и «ошибки» в любом другом случае. Поскольку я не хочу, чтобы кнопка была отписана при ошибке, я использую функцию catch.Правильно ли это выполнение тайм-аута в Reactive Cocoa?

Что я хочу: я хочу, чтобы тайм-аут срабатывал через 2 секунды, если loginSignal не был запущен. Правильно ли это сделано? Правильно ли это «реактивный путь»?

[[[[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, который является хорошим центром для связывания сигналов в интерфейс:

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 
}]; 

Сигнал автоматически отключит кнопку во время ее выполнения. Если вам нужно отключить другие части пользовательского интерфейса, вы можете использовать «исполняемый» сигнал команды.

[[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

+0

Я никогда не использовал таймаут, но смотрел на код, который, похоже, не задерживает исходный полный сигнал. У вас есть более подробная информация о вашем loginSignal? – kamidude

+0

Я работал с sendNext: 'on Error внутри моего loginSignal, так как у меня были проблемы с отмененными подписками в прошлом при использовании ошибки. Теперь я использую isendError: «при любой ошибке, и теперь это работает как шарм !!! Большое спасибо!! – beseder

Смежные вопросы