Я все еще довольно новичок в мире ReactiveCocoa, и я просто хотел прояснить этот общий сценарий. Я заметил, что другие люди борются с этим вопросом на GitHub и SO, но мне все еще не хватает правильного ответа.
Следующий пример работает, но я видел, что Джастин Саммерс говорит, что подписки внутри подписок или подписки в целом могут быть запахом кода. Поэтому я хочу попытаться избежать вредных привычек при изучении этой новой парадигмы.
Итак, пример (с использованием MVVM) довольно прост:
- ViewController содержит кнопку входа в систему, которая связана с командой входа в модель представления.
- ViewModel определяет действие команды и имитирует некоторый сетевой запрос для этого примера.
- ViewController подписывается на executingSignals команды и может различать три типа возврата: следующий, ошибка и полный.
И код.
1 (Вьюконтроллер):
RAC(self.loginButton, rac_command) = RACObserve(self, viewModel.loginCommand);
2 (ВьюМодель):
self.loginCommand = [[RACCommand alloc] initWithEnabled:canLoginSignal
signalBlock:^RACSignal *(id input) {
return [[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
BOOL success = [username isEqualToString:@"user"] && [password isEqualToString:@"password"];
// Doesn't really make any sense to use sendNext here, but lets include it to test whether we can handle it in our viewmodel or viewcontroller
[subscriber sendNext:@"test"];
if (success)
{
[subscriber sendCompleted];
} else {
[subscriber sendError:nil];
}
// Cannot cancel request
return nil;
}] materialize];
}];
3 (Вьюконтроллер):
[self.viewModel.loginCommand.executionSignals subscribeNext:^(RACSignal *execution) {
[[execution dematerialize] subscribeNext:^(id value) {
NSLog(@"Value: %@", value);
} error:^(NSError *error) {
NSLog(@"Error: %@", error);
} completed:^{
NSLog(@"Completed");
}];
}];
Как бы вы сделали это в духе ReactiveCococa?