itinance
itinance

Reputation: 12388

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 :)

Upvotes: 1

Views: 359

Answers (1)

Justin Spahr-Summers
Justin Spahr-Summers

Reputation: 16973

-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.

Upvotes: 4

Related Questions