I have one RACSignal that carries NSArray of objects of class Bookmark
RACSignal *bookmarksSignal = ... // Carries @[[[Bookmark alloc] init], ...]
And two RACCommands to add and delete bookmark
RACCommand *addBookmarkCommand = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input){
return [RACSignal return:input];
}];
...
[addBookmarkCommand execute: bookmark1];
RACCommand *deleteBookmarkCommand = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input){
return [RACSignal return:input];
}];
...
[deleteBookmarkCommand execute: bookmark2]
Commands are executed on user interaction. How can I combine bookmarksSignal
and executions signals of both commands to create signal that carries NSArray of bookmarks that contains original bookmarks with those added by addBookmarkCommand
and without those removed by deleteBookmarkCommand
?
(bookmarks are compared by url
property)
I'm afraid that I'm missing something obvious, but I can't figure out how to do this in pure way.
For lack of time, I'll go with a more laconic answer compared to @IanHenry's :)
For anything here that doesn't make sense, please comment and I'll be happy explain in detail.
// Map additions into blocks that add the bookmark to the given mutable array.
RACSignal *addBookmarkSignal = [[addBookmarkCommand concat] map:^(Bookmark *bookmark) {
return ^(NSMutableArray *bookmarks) {
return [bookmarks addObject:bookmark];
};
}];
// Map deletions into blocks that remove the bookmark from the given mutable array.
RACSignal * addBookmarkSignal = [[deleteBookmarkCommand concat] map:^(Bookmark *bookmark) {
return ^(NSMutableArray *bookmarks) {
[bookmarks removeObject:bookmark];
};
}];
// Combine the add and delete functions into a single signal.
RACSignal *updatesSignal = [RACSignal merge:@[addBookmarkSignal, addBookmarkSignal]];
RACSignal *updatedBookmarksSignal = [[bookmarksSignal
// Each time bookmarksSignal sends an array, this -map: builds a
// signal that updates the latest list of bookmarks, and sends it.
map:^(NSArray *bookmarks) {
NSMutableArray *mutableBookmarks = [bookmarks mutableCopy];
// Using the update blocks from the add/delete commands,
// produce the modified list of bookmarks.
return [[updatesSignal
map:^(void (^update)(NSMutableArray *)) {
update(mutableBookmarks);
return [mutableBookmarks copy];
}]
startWith:bookmarks];
}]
// When bookmarksSignal sends anew, switch to the newest signal of updates.
switchToLatest];