In realtà è molto buon approccio per risolvere questo problema con ReactiveCocoa.
Si desidera ottenere il testo mentre l'utente sta digitando o nella parola "Reattivo" che si desidera "Stream" del testo di input, Se l'utente è un veloce typer, si desidera eseguire la richiesta al server solo se il testo di ricerca è invariato per un breve periodo di tempo, puoi farlo da solo (usando Delegate, NSTimer), ma con ReactiveCocoa è davvero semplice e leggibile.
@property (weak, nonatomic) IBOutlet UISearchBar *searchBar;
[[textSignal throttle:0.4]subscribeNext:^(NSString* searchText) {
[[SearchService sharedInstance]search:searchText completed:^(NSString *searchResult, NSError *error) {
NSLog(@"searchResult: %@",searchResult);
}];
}];
Supponiamo che la classe SearchService restituisca la ricerca e la lunghezza del testo di ricerca dopo 2,5 secondi.
@implementation SearchService
typedef void(^CompletedResults)(NSString *searchResult, NSError *error);
- (void)search:(NSString *)text completed:(CompletedResults)handler {
NSString *retVal = [NSString stringWithFormat:@"%@ = %@", text, @([text length])];
// Here you should to do your network call and and return the response string
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[NSThread sleepForTimeInterval:2.5];
if (handler){
handler(retVal, nil);
}
});
}
E con la sola riga di codice è possibile limitare il testo di input.
realtà ReactiveCocoa non prevede una categoria di UISearchBar, ma non è così complicato da implementare (È possibile trovare UISearchBar (RAC) categoria hire)
Cosa importante che si desidera porsi è, che cosa accadrà se hai già inviato la richiesta al server e prima di ottenere la risposta l'utente continua a digitare? Probabilmente si desidera annullare la richiesta precedente (e rilasciare tutte le risorse) e inviare una nuova richiesta al server con il nuovo testo di ricerca. di nuovo puoi farlo da solo ma con ReactiveCocoa è molto semplice, se inizi a pensare a cose come segnali.
È necessario avvolgere il servizio di ricerca che restituisce "flusso" di risultati dal server.
@implementation SearchService
- (RACSignal *)search:(NSString *)text {
return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[self search:text completed:^(NSString *searchResult, NSError *error) {
[subscriber sendNext:searchResult];
[subscriber sendCompleted];
}];
return nil;
}];
}
Ora tutto ciò che dovete fare è quello di mappare ogni testo da ricercare per segnalare di conseguenza dal server e chiamare per switchToLatest.
[[[[textSignal throttle:0.4]
map:^id(NSString* searchText) {
return [[SearchService sharedInstance]search:searchText];
}]
switchToLatest]
subscribeNext:^(NSString* searchResult) {
NSLog(@"searchResult: %@",searchResult);
}];
E un'altra cosa, probabilmente quando si ottiene la risposta dal server che si desidera aggiornare l'interfaccia utente. E devi farlo sul thread principale. Anche qui con ReactiveCocoa è davvero semplice, basta aggiungere deliverOn: RACScheduler.mainThreadScheduler.
[[[[[textSignal throttle:0.4]
map:^id(NSString* searchText) {
NSLog(@"Get Text after throttle");
return [[SearchService sharedInstance]search:searchText];
}]
switchToLatest]
deliverOn:RACScheduler.mainThreadScheduler]
subscribeNext:^(NSString* searchResult) {
if ([NSThread isMainThread]){
NSLog(@"is MainThread");
}
else{
NSLog(@"is not MainThread");
}
NSLog(@"searchResult: %@",searchResult);
}];
Buona fortuna :)
Se si scrive il codice con Swift, dare un'occhiata a ReactiveSwift GitHub - estensioni reattivi per Swift, Ispirato da ReactiveCocoa
Hai guardato 'RACSignal' di metodo 'throttle'? –
@ MichałCiuba è un metodo molto valido, dovresti fare una risposta. –
Stai usando ReactiveCocoa 2? –