Вот мой основной сценарий:При помощи кнопки Войти Reactivecocoa срабатывает только один раз
Я делаю простой login
рамки, так что я получил два text field
, один для пользователя, а другой для пароля, и конечно Логин button
.
Теперь я связываю их с RACSignal
как это:
RACSignal *validPasswordSignal = [passwordTextField.rac_textSignal map:^id(NSString *text)
{
return @([self isPasswordValid:text]);
}];
RACSignal *validUsernameSignal = [usernameTextField.rac_textSignal map:^id(NSString *text)
{
return @([self isUsernameValid:text]);
}];
и объединить два сигнала (имя пользователя и пароль) в один, как это:
RACSignal *submitActiveSignal = [RACSignal combineLatest:@[validpasswordSignal, validUsernameSignal] reduce:^id(NSNumber *validPW, NSNumber *validUN)
{
return @(validPW.boolValue && validUN.boolValue);
}];
Конечно, мне нужен метод, чтобы представить сигналы для имени пользователя и пароля с запросом на сервер, поэтому у меня оно выглядит следующим образом:
-(RACSignal *)submitSignal
{
return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber)
{
[[[RequestClass alloc] init] requestWithUsername:_usernameTextField.text.trim password:_passwordTextField.text.trim completionHandler:^(MyResult *results, NSURLResponse *response, NSError *error)
{
if (!error)
{
if (results.code == 0)
{
[subscriber sendNext:@(YES)];
[subscriber sendCompleted];
}
else
{
NSError *invalidError = [NSError errorWithDomain:MyErrorDomain code:MyErrorInvalidSigniture userInfo:@{@"NSLocalizedDescription": results.message}];
[subscriber sendError:invalidError];
}
}
else
{
[subscriber sendError:error];
}
}];
return nil;
}];
}
Тогда мне нужно, чтобы моя кнопка Войти поймать сигнал от абонента sendNext
и sendError
, так что я сделал это так:
//subscribeNext
[[[[_submitButton rac_signalForControlEvents:UIControlEventTouchUpInside]
doNext:^(id x)
{
_submitButton.enabled = NO;
}]
flattenMap:^RACStream *(id value)
{
return [self submitSignal];
}]
subscribeNext:^(NSNumber *signal)
{
_submitButton.enabled = YES;
BOOL success = signal.boolValue;
if (success)
{
[self successCallback];
}
else
{
//do sth
}
}];
//subscribeError
[[[[_submitButton rac_signalForControlEvents:UIControlEventTouchUpInside]
doNext:^(id x)
{
_submitButton.enabled = NO;
}]
flattenMap:^RACStream *(id value)
{
return [self submitSignal];
}]
subscribeError:^(NSError *error)
{
[self failureCallbackWithError:error];
}];
Выше reactivecocoa
код, который я написал для моей процедуры авторизации. Когда пароль и имя пользователя были правильными, сигнал перейдет в блок ответа sendNext
: subscribeNext
, , но проблема в том, что учетные данные были неверными, а ошибка с сервером была возвращена, ни sendError
, ни subscribeError
не будут запущены.
Это как сигнал ошибки был потерян или что-то в этом роде.
Я не уверен, что я использую правильные методы реакции, чтобы обрабатывать сигнал успеха и сигнал ошибки.
Так что, пожалуйста, помогите, спасибо.
Также, пожалуйста, дайте мне знать, если я не буду разбираться в моем вопросе.
Я не знаю, устранит ли это проблему, но вы не должны подписываться на событие касания кнопки дважды - вы будете отправлять два запроса каждый раз, когда он прослушивается. Используйте 'subscribeNext: error' для обработки как успеха, так и неудачи в одной подписке. –
@PatrickBacon Я пробовал свой путь, но все еще не работал.Я нажал кнопку один раз, и это вызвало либо subscribeNext-блок, либо блок ошибок, который хорош; но когда я нажал кнопку во второй раз, ничего не произошло. В методе 'trigger' я помещаю' [абонент sendNext: @ (YES)]; [абонент sendCompleted] 'и' [абонент sendError: ошибка] '. Не могли бы вы взглянуть и помочь мне? – Boris
Убедитесь, что вы повторно включили кнопку в обоих случаях успеха ('subscribeNext:') и ошибки ('error:'). Вероятно, вы также должны добавить 'deliverOnMainThread' после' flattenMap', чтобы убедиться, что изменения в пользовательском интерфейсе происходят в основном потоке. –