Reputation: 2773
my app uses a SearchGraphical to search for registered users in the app ... My problem is that when I go to do research shows me the duplicate results as:
Name Search: Francesca Result: Francesca (1 cell) Francesca (2 Cell)
**09/14/2013 22:18:17.817 Unipot v.02 [63396: a0b] Successfully retrieved 1 scores.
09/14/2013 22:18:17.818 Unipot v.02 [63396: a0b] Content: Antonella Folino
09/14/2013 22:18:17.818 Unipot v.02 [63396: a0b] Content: francesca Folino
09/14/2013 22:18:17.818 Unipot v.02 [63396: a0b] Content: francesca Folino
09/14/2013 22:18:17.819 Unipot v.02 [63396: a0b] Content: francesca Folino**
I do not understand why. This problem arises when you type in the search bar is done quickly.
In addition, the app crashes after a short time by returning to this notice:
**Terminating apt two to uncaught exception 'NSRangeException', reason: '*** - [__NSArrayM objectAtIndex:]: index 10 beyond bounds [0 .. 9] '**
This is my file. M Can you help me??
#import "Ricerca.h"
#import "Custom.h"
@interface Ricerca () <UISearchDisplayDelegate, UISearchBarDelegate>
@property (nonatomic, strong) UISearchDisplayController *searchController;
@property (nonatomic, strong) NSMutableArray *searchResults;
@end
@implementation Ricerca
- (void)viewDidLoad {
[super viewDidLoad];
[self loadObjects];
self.searchResults = [NSMutableArray array];
}
- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if (self) {
self.parseClassName = @"_User";
self.paginationEnabled = YES;
self.loadingViewEnabled = NO;
self.objectsPerPage = 10;
}
return self;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait || UIInterfaceOrientationIsLandscape(interfaceOrientation));
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath object:(PFObject *)object {
UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:@"Cell"];
if (!cell)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"Cell"];
}
// Configure the cell
UIColor *color = [[UIColor alloc] initWithRed:0.0 green:0.0 blue:0.0 alpha:0.0];
cell.detailTextLabel.backgroundColor = color;
cell.textLabel.backgroundColor = color;
if (tableView == self.tableView) {
cell.textLabel.text = [object objectForKey:@"username"];
}
else {
PFObject *searchedUser = [self.searchResults objectAtIndex:indexPath.row];
NSString *content = [searchedUser objectForKey:@"username"];
cell.textLabel.text = content;
NSLog(@"Content: %@", content);
}
return cell;
}
-(void)filterResults:(NSString *)searchTerm {
[self.searchResults removeAllObjects];
PFQuery *query = [PFQuery queryWithClassName:@"_User"];
[query whereKey:@"username" containsString:searchTerm];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
// The find succeeded.
NSLog(@"Successfully retrieved %d scores.", objects.count);
[self.searchResults addObjectsFromArray:objects];
[self.searchDisplayController.searchResultsTableView reloadData];
} else {
// Log details of the failure
NSLog(@"Error: %@ %@", error, [error userInfo]);
}
}];
}
-(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString {
[self filterResults:searchString];
return YES;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (tableView == self.tableView) {
return self.objects.count;
} else {
return self.searchResults.count;
}
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (tableView == self.tableView) {
[super tableView:tableView didSelectRowAtIndexPath:indexPath];
} else {
[super tableView:tableView didSelectRowAtIndexPath:indexPath];
}
}
Upvotes: 0
Views: 1201
Reputation: 16874
In your filterResults:
method you are calling [self.searchResults addObjectsFromArray:objects];
, this will add those results to what is already there. In the case where this method is getting hit multiple times before the first query finishes you could end up with the following scenario:
As you can see, there's no way to be sure when a query will finish, they might come back in a different order, and might not come back before you call the method again.
In this case it is hard to know what to do, you could empty self.searchResults
in the success block, but in a case like above the final contents will be for the first query instead of the second query.
You could implement some kind of cancel/ignore-results option, or add a delay to the start of the query and hope for the best. Either way I would suggest reading up on threading issues and async operations.
Upvotes: 1