Thread: search crashing
View Single Post
  #3 (permalink)  
Old April 4th, 2012, 01:05 AM
Jule Jule is offline
Authorized User
Points: 62, Level: 1
Points: 62, Level: 1 Points: 62, Level: 1 Points: 62, Level: 1
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: Mar 2011
Posts: 16
Thanks: 8
Thanked 0 Times in 0 Posts
Default Working Code

I decided to have one final attempt at this before troubling ThePianoGuy. Started from Scratch, the code worked. No crashing no problems every great.

Checked code against non working project, found a typo used a instead of @, but it still won't work. Copied and pasted new project into old and works like a charm.

Still can't see where I went wrong. If anyone is bored and wants to try

here is non-working code

Code:
#import "RootViewController.h"


@implementation RootViewController

@synthesize croplists;
@synthesize filteredCrops;
@synthesize searchBar;
@synthesize searchController;



- (void)viewDidLoad {
    [super viewDidLoad];
	
	self.croplists = [NSMutableArray arrayWithCapacity:1];
	
	NSMutableArray *croplistsTemp;
	
	// get the DBAccess object
	DBAccess *dbAccess = [[DBAccess alloc] init];
	
	// get the array from the database
	croplistsTemp = [dbAccess getAllCropLists];
	
	// close the database finished with it
	[dbAccess closeDatabase];
	
	// release the dbAccess object to free its memory
	[dbAccess release];
	
    // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
    // self.navigationItem.rightBarButtonItem = self.editButtonItem;

	UILocalizedIndexedCollation *indexedCollation = [UILocalizedIndexedCollation currentCollation];
	
	// iterate over the crops, populating their section number
	for (CropList *theCropList in croplistsTemp) {
		NSInteger section = [indexedCollation sectionForObject:theCropList collationStringSelector:@selector(name)];
		theCropList.section = section;
			
	}
	
	// get the count of the number of sections
	NSInteger sectionCount = [[indexedCollation sectionTitles] count];

	// create an array to hold the sub arrays
	NSMutableArray *sectionsArray = [NSMutableArray arrayWithCapacity:sectionCount];
	
	// interate over each section, creating each sub array
	for (int i=0; i<=sectionCount; i++) {
		NSMutableArray *singleSectionArray = [NSMutableArray arrayWithCapacity:1];
		[sectionsArray addObject:singleSectionArray];
	}
	
	// iterate over the crops putting each crop into the correct sub-array 
	for (CropList *theCropList in croplistsTemp) {
		[(NSMutableArray *) [sectionsArray objectAtIndex:theCropList.section] addObject:theCropList];
	}
	
	// iterate over each section array to sort the items in the section
	for (NSMutableArray *singleSectionArray in sectionsArray) {
		// use the UILocalizedIndexedCollation sortedArrayFromArray: method to sort each array
		NSArray *sortedSection = [indexedCollation sortedArrayFromArray:singleSectionArray collationStringSelector:@selector(name)];
		[self.croplists addObject:sortedSection];
	}
	
	// create search bar
	self.searchBar = [[[UISearchBar alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 320.0f, 44.0f)] autorelease];
	self.tableView.tableHeaderView = self.searchBar;
	
	// create and configure the search controller
	self.searchController = [[[UISearchDisplayController alloc] initWithSearchBar:self.searchBar contentsController:self] autorelease];
	self.searchController.searchResultsDataSource = self;
	self.searchController.searchResultsDelegate = self;
	
}	

	
/*
 - (void)viewWillAppear:(BOOL)animated {
 [super viewWillAppear:animated];
 }
 */
/*
 - (void)viewDidAppear:(BOOL)animated {
 [super viewDidAppear:animated];
 }
 */
/*
 - (void)viewWillDisappear:(BOOL)animated {
 [super viewWillDisappear:animated];
 }
 */
/*
 - (void)viewDidDisappear:(BOOL)animated {
 [super viewDidDisappear:animated];
 }
 */


 // Override to allow orientations other than the default portrait orientation.
 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
 // Return YES for supported orientations.
	 return YES; //(interfaceOrientation == UIInterfaceOrientationPortrait);
 }



#pragma mark Table view methods

// Customize the number of sections in the table view.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
	// is the request for numberOfRowsInSection for the regular table?
	if (tableView == self.tableView)
	{
		// return the count of the crops as normal
		return [self.croplists count];
	}
	return 1;
}


// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
	// is the request for numberOfRowsInSection for the regular table?
	if (tableView == self.tableView)
	{
		// just return the count of the crops as normal
		return [[self.croplists objectAtIndex:section] count];
	}
		// count for the filtered table
		// first, flatten the array of arrays self.croplists
		NSMutableArray *flattenedArray = [[NSMutableArray alloc] initWithCapacity:1];
		for (NSMutableArray *theArray in self.croplists)
		{
			for (int i=0; i<[theArray count]; i++)
			{
				[flattenedArray addObject:[theArray objectAtIndex:i]];
			}
		
		}
	
	// setup the NSPredicate to filter the rows
	NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name begins with[c] %@", self.searchBar.text];
	self.filteredCrops = [flattenedArray filteredArrayUsingPredicate:predicate];
	
	// clean up flattened array
	[flattenedArray release];
	
	return self.filteredCrops.count;
				  
}
				  

// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *CellIdentifier = @"Cell";
    
    CropTableViewCell *cell = (CropTableViewCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[CropTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }
    
	// Configure the cell.
	cell.accessoryType = UITableViewCellAccessoryNone;
	
	// is the request for cellForRowAtIndexPath for the regular path?
	if (tableView == self.tableView)
	{
		
		// get the crop object
		CropList *croplist = [[self.croplists objectAtIndex:[indexPath section]] objectAtIndex:[indexPath row]];
	
		// set the crop to be used to draw the cell
		[cell setCropList:croplist];
	
		return cell;
	}
	
	// get the crop object
	CropList *croplist = [self.filteredCrops objectAtIndex:[indexPath row]];
	// set the crop to be used to draw the cell
	[cell setCropList:croplist];
	
	return cell;
}

	
// override to support row selection in the table view	
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {	
		
	// get the crop that corresponds with the cell selected
	CropList *croplist;
		
	if (tableView == self.tableView)
	{
		// get the crop that corresponds with the touched cell
		croplist = [[self.croplists objectAtIndex:[indexPath section]] objectAtIndex:[indexPath row]];
    }
					  
    else {
		croplist = [self.filteredCrops objectAtIndex:[indexPath row]];
    }
					  
	  
   //initialise detail view controller from the NIB xib file
   CropListDetailViewController *cropListDetailViewController = [[CropListDetailViewController alloc] initWithNibName:@"CropListDetailViewController" bundle:nil];
					  
   // set titles of detail page
   [cropListDetailViewController setTitle:croplist.name];
					  
   // push detail controller to the stack
   [self.navigationController pushViewController:cropListDetailViewController animated:YES];
					  
   // populate the details
   [cropListDetailViewController setLabelsForCropList:croplist];
					  
   // release the view controller
   [cropListDetailViewController release];
					  
}    
					  
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
	// make sure that the section will contain some data
	if ([[self.croplists objectAtIndex:section] count] >0) {
		
		// if it does, get the section title from the UILocalizedIndexedCollation object
		return [[[UILocalizedIndexedCollation currentCollation] sectionTitles] objectAtIndex:section];
	}
	return nil;
}

- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
	if (tableView == self.tableView)
	{
		
		// setup the index titles from the UILocaliszedIndexedCollation 
		return [[UILocalizedIndexedCollation currentCollation] sectionIndexTitles];
	}
	return nil;
}
	
- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex: (NSInteger)index {
	// link the sections to the labels in the table
	return [[UILocalizedIndexedCollation currentCollation] sectionForSectionIndexTitleAtIndex:index];
}
	

/*
 // Override to support conditional editing of the table view.
 - (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
 // Return NO if you do not want the specified item to be editable.
 return YES;
 }
 */


/*
 // Override to support editing the table view.
 - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
 
 if (editingStyle == UITableViewCellEditingStyleDelete) {
 // Delete the row from the data source.
 [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
 }   
 else if (editingStyle == UITableViewCellEditingStyleInsert) {
 // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view.
 }   
 }
 */


/*
 // Override to support rearranging the table view.
 - (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath {
 }
 */


/*
 // Override to support conditional rearranging of the table view.
 - (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
 // Return NO if you do not want the item to be re-orderable.
 return YES;
 }
 */

#pragma mark -
#pragma mark Memory Management

- (void)didReceiveMemoryWarning {
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];
    
    // Relinquish ownership any cached data, images, etc that aren't in use.
}

- (void)viewDidUnload {
    // Relinquish ownership of anything that can be recreated in viewDidLoad or on demand.
    // For example: self.myOutlet = nil;
}



- (void)dealloc {
	
  [super dealloc];
	
}
				  


@end
and the working code

Code:
#import "RootViewController.h"


@implementation RootViewController

@synthesize croplists;
@synthesize filteredCrops;
@synthesize searchBar;
@synthesize searchController;



#pragma mark -
#pragma mark View lifecycle


- (void)viewDidLoad {
    [super viewDidLoad];
	
	self.croplists = [NSMutableArray arrayWithCapacity:1];
	
	NSMutableArray *croplistsTemp;
	
	// get the DBAccess object
	DBAccess *dbAccess = [[DBAccess alloc] init];
	
	// get the array from the database
	croplistsTemp = [dbAccess getAllCropLists];
	
	// close the database finished with it
	[dbAccess closeDatabase];
	
	// release the dbAccess object to free its memory
	[dbAccess release];
	
    // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
    // self.navigationItem.rightBarButtonItem = self.editButtonItem;
	UILocalizedIndexedCollation *indexedCollation = [UILocalizedIndexedCollation currentCollation];
	
	// iterate over the crops, populating their section number
	for (CropList *theCropList in croplistsTemp) {
		NSInteger section = [indexedCollation sectionForObject:theCropList collationStringSelector:@selector(name)];
		theCropList.section = section;
		
	}
	
	// get the count of the number of sections
	NSInteger sectionCount = [[indexedCollation sectionTitles] count];
	
	// create an array to hold the sub arrays
	NSMutableArray *sectionsArray = [NSMutableArray arrayWithCapacity:sectionCount];
	
	// interate over each section, creating each sub array
	for (int i=0; i<=sectionCount; i++) {
		NSMutableArray *singleSectionArray = [NSMutableArray arrayWithCapacity:1];
		[sectionsArray addObject:singleSectionArray];
	}
	
	// iterate over the crops putting each crop into the correct sub-array 
	for (CropList *theCropList in croplistsTemp) {
		[(NSMutableArray *) [sectionsArray objectAtIndex:theCropList.section] addObject:theCropList];
	}
	
	// iterate over each section array to sort the items in the section
	for (NSMutableArray *singleSectionArray in sectionsArray) {
		// use the UILocalizedIndexedCollation sortedArrayFromArray: method to sort each array
		NSArray *sortedSection = [indexedCollation sortedArrayFromArray:singleSectionArray collationStringSelector:@selector(name)];
		[self.croplists addObject:sortedSection];
	}
	
	// create searchBar
	self.searchBar = [[[UISearchBar alloc] initWithFrame: CGRectMake(0.0f, 0.0f, 320.0f, 44.0f)] autorelease];
	self.tableView.tableHeaderView = self.searchBar;
	
	// create search Controller
	self.searchController = [[[UISearchDisplayController alloc] initWithSearchBar:self.searchBar contentsController:self] autorelease];
	self.searchController.searchResultsDataSource  = self;
	self.searchController.searchResultsDelegate = self;
	
	
}


/*
 - (void)viewWillAppear:(BOOL)animated {
 [super viewWillAppear:animated];
 }
 */
/*
 - (void)viewDidAppear:(BOOL)animated {
 [super viewDidAppear:animated];
 }
 */
/*
 - (void)viewWillDisappear:(BOOL)animated {
 [super viewWillDisappear:animated];
 }
 */
/*
 - (void)viewDidDisappear:(BOOL)animated {
 [super viewDidDisappear:animated];
 }
 */

/*
 // Override to allow orientations other than the default portrait orientation.
 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
 // Return YES for supported orientations.
 return (interfaceOrientation == UIInterfaceOrientationPortrait);
 }
 */



#pragma mark Table view methods

// Customize the number of sections in the table view.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
	
	// is the request for numberOfRowsInSection for the regular table
	if (tableView == self.tableView)
	{
		// just return the count of the crops like before
		return [self.croplists count];
	}
	
	return 1;
	
}


// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
	// is the request for numberOfRowsInSection for the regular table
	if (tableView == self.tableView)
	{
		
		// just return the count of the crops like before
		return [[self.croplists objectAtIndex:section] count];
		
	}
	
	// count for the filtered table
	// first, flatten the array of arrays self.crops
	NSMutableArray *flattenedArray = [[NSMutableArray alloc] initWithCapacity:1];
	for (NSMutableArray *theArray in self.croplists)
	{
		for (int i=0; i<[theArray count]; i++) 
		{
			[flattenedArray addObject:[theArray objectAtIndex:i]];
		}
	}
	
	// setup an NSPredicate to filter the rows
	NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name beginswith[c]%@", self.searchBar.text];
	self.filteredCrops = [flattenedArray filteredArrayUsingPredicate:predicate];
	
	//clean up the array
	[flattenedArray release];
	
	return self.filteredCrops.count;
	
}


// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
    static NSString *CellIdentifier = @"Cell";
    
    CropTableViewCell *cell = (CropTableViewCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[CropTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }
    
	// Configure the cell.
	cell.accessoryType = UITableViewCellAccessoryNone;
	
	// is the request for cellForRowAtIndexPath for the regular table?
	if (tableView == self.tableView)
	{
		
		// get the crop object
		CropList *croplist = [[self.croplists objectAtIndex:[indexPath section]] objectAtIndex:[indexPath row]];
		
		
		// set the crop to be used to draw the cell
		[cell setCropList:croplist];
		
		return cell;
	}
	
	// get the crop object
	CropList* croplist = [self.filteredCrops objectAtIndex:[indexPath row]];
	
	// set the crop to be used to draw the cell
	[cell setCropList:croplist];
	
	return cell;
}



/*
 // Override to support conditional editing of the table view.
 - (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
 // Return NO if you do not want the specified item to be editable.
 return YES;
 }
 */


/*
 // Override to support editing the table view.
 - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
 
 if (editingStyle == UITableViewCellEditingStyleDelete) {
 // Delete the row from the data source.
 [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
 }   
 else if (editingStyle == UITableViewCellEditingStyleInsert) {
 // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view.
 }   
 }
 */


/*
 // Override to support rearranging the table view.
 - (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath {
 }
 */


/*
 // Override to support conditional rearranging of the table view.
 - (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
 // Return NO if you do not want the item to be re-orderable.
 return YES;
 }
 */


#pragma mark -
#pragma mark Table view delegate

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    
	// get the crop that corresponds with the cell selected
	CropList *croplist;
	if (tableView == self.tableView)
	{	
		//get the crop that corresponds iwth the touched cell
		croplist = [[self.croplists objectAtIndex:[indexPath section]] objectAtIndex:[indexPath row]];
	}
	else {
		croplist = [self.filteredCrops objectAtIndex:[indexPath row]];
		
	}
	
	
	//initialise detail view controller from the NIB xib file
	CropListDetailViewController *cropListDetailViewController = [[CropListDetailViewController alloc] initWithNibName:@"CropListDetailViewController" bundle:nil];
	
	// set titles of detail page
	[cropListDetailViewController setTitle:croplist.name];
	
	// push detail controller to the stack
	[self.navigationController pushViewController:cropListDetailViewController animated:YES];
	
	// populate the details
	[cropListDetailViewController setLabelsForCropList:croplist];
	
	// release the view controller
	[cropListDetailViewController release];
	
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
	// make sure that the section will contain some data
	if ([[self.croplists objectAtIndex:section] count] >0) {
		
		// if it does, get the section title from the UILocalizedIndexedCollation object
		return [[[UILocalizedIndexedCollation currentCollation] sectionTitles] objectAtIndex:section];
	}
	return nil;
}

- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
	if (tableView == self.tableView)
	{
		
		// setup the index titles from the UILocaliszedIndexedCollation 
		return [[UILocalizedIndexedCollation currentCollation] sectionIndexTitles];
	}
	return nil;
}

- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex: (NSInteger)index {
	// link the sections to the labels in the table
	return [[UILocalizedIndexedCollation currentCollation] sectionForSectionIndexTitleAtIndex:index];
}



#pragma mark -
#pragma mark Memory management

- (void)didReceiveMemoryWarning {
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];
    
    // Relinquish ownership any cached data, images, etc that aren't in use.
}

- (void)viewDidUnload {
    // Relinquish ownership of anything that can be recreated in viewDidLoad or on demand.
    // For example: self.myOutlet = nil;
}


- (void)dealloc {
    [super dealloc];
}


@end


Thanks Bob for the offer of testing code.