I'm trying to write a reactive solution for the following scenario.
Tapping on a button, if there are some entities available in the database the user must be pushed to new view controller, otherwise an attempt to download these entities should be done and the check performed again.
Here's what I've got so far:
// VIEW CONTROLLER
self.button.rac_command = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) {
return self.viewModel.rac_checkEntitiesAvailability;
}];
[self.button.rac_command.executionSignals.flatten subscribeNext:^(id x) {
if([x boolValue] == YES) {
// Entities available, can perform segue
} else {
// Error
}];
// VIEW-MODEL
- (RACSignal*)rac_checkEntitiesAvailability {
return [[RACSignal return:@([Entity MR_countOfEntities] > 0)]
flattenMap:^RACStream *(id entitiesAvailable) {
if([entitiesAvailable boolValue]) {
return [RACSignal return:@YES];
} else {
return [[[self rac_downloadEntities] flattenMap:^RACStream *(id value) {
// This takes into account network problems too
return [RACSignal return:@([Entity MR_countOfEntities] > 0)];
}];
}
}];
}
It seems to work but as I'm new to the ReactiveCocoa world I'm not sure it's really correct or could be written in less redundant way.
Many thanks, DAN
I would honestly advise against direct binding of control events when UIControls are involved. If you use a RACCommand (declared and created in your viewModel) you can easily bind your UI to the state of the download (executing signal), show alert messages upon failures and presenting new UI upon success (if needed). Your revised version of the code seems good to me, but I would probably simplify your inner signal: you don't need to wrap a boolean "immediate" variable around a return signal (=you don't need a signal to know how many entities you have in your CoreData model, it's a synchronous operation). Something like this (check syntax, it may be wrong with all those square brackets)
[RACSignal defer:^RACSignal *{
if([Entity MR_countOfEntities] > 0) {
return [RACSignal return:@YES];
} else {
return [[self rac_downloadEntities] flattenMap:^RACStream *(id value) {
// This takes into account network problems too
return [RACSignal return:@([Entity MR_countOfEntities] > 0)];
}];
}];