Search code examples
objective-creactive-cocoa

ReactiveCocoa: throttle never executes / not working


I try to subscribe to a signal with throttle, but it never executes.

I have a UISearchController (Attention: UISearchController from iOS8, not the older UISearchDisplayController, which works quiet better and has thousands of working tutorials and examples in the web) and want to make API-Requests while the user is typing. To let the traffic being low, i don't want to start API-Requests with each key the user is pressing, but when the user stops for a while, say 500 ms after the last keypress.

Since we're unable to reference the TextField in the SearchBar of the UISearchController, we use the delegates from UISearchController:

To get the latest typed text of the Textfield in the Searchbar, I use this:

#pragma mark - UISearchResultsUpdating

- (void)updateSearchResultsForSearchController:(UISearchController *)searchController {
    NSString *searchText = searchController.searchBar.text;

    // strip out all the leading and trailing spaces
    NSString *strippedString = [searchText stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];

    if([strippedString isEqualToString:self.currentFilter]) {
        return;
    }
    self.currentFilter = strippedString;
}

The property currentFilter keeps the current search string.

Also, i have a RACObserve on the currentFilter-Property to react on every change which is made to this property:

[RACObserve(self, currentFilter) subscribeNext:^(NSString* x) {
    NSLog(@"Current Filter: %@", x);
    // do api calls and everything else
}];

Now i want to throttle this signal. But when i implement the call to throttle, nothing happens. SubscribeNext will never be called:

[[RACObserve(self, currentFilter) throttle:500] subscribeNext:^(NSString* x) {
    NSLog(@"%@", x); // will never be called
}];

How to achieve to throttle inputs in a searchbar? And what is wrong here?

UPDATE

i found a workaround besides ReactiveCocoa thanks to @malcomhall. I moved the code within the updateSearchResultsForSearchController-delegate method into a separate method and schedule it with performSelector and cancel this scheduler with cancelPreviousPerformRequestsWithTarget.

- (void)updateSearchResultsForSearchController:(UISearchController *)searchController {

    [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(useTextSearchQuery) object:nil];
    [self performSelector:@selector(useTextSearchQuery) withObject:nil afterDelay:1.0];

}

Anyway, i want still understand how "throttle" from ReactiveCocoa is working and why not in this case :)


Solution

  • -throttle: accepts an NSTimeInterval, which is a floating-point specification of seconds, not milliseconds.

    Given the code in the question, I expect you would see results after 500 seconds have elapsed.