Problem with UISearchBar and NSMutableArray - iphone

I have a tableview with a search bar. I want to search my whole core data database.
I loaded everything into an array here:
NSEntityDescription *entityDescription = [NSEntityDescription entityForName:#"Entity" inManagedObjectContext:managedObjectContext];
NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
[request setEntity:entityDescription];
NSError *error = nil;
NSArray *array = [managedObjectContext executeFetchRequest:request error:&error];
self.myArray = array;
I'm then searching using this method but getting an error:
- (void) searchTableView {
NSString *searchText = searchBar.text;
NSMutableArray *searchArray = [[NSMutableArray alloc] init];
for (NSDictionary *dictionary in myArray)
{
NSString *value = [dictionary objectForKey:#"name"];
[searchArray addObject:value];
}
for (NSString *sTemp in searchArray)
{
NSRange titleResultsRange = [sTemp rangeOfString:searchText options:NSCaseInsensitiveSearch];
if (titleResultsRange.length > 0)
[copyListOfItems addObject:sTemp];
}
[searchArray release];
searchArray = nil;
}
But when I search, I get the crash here:
MedicalCode *code = [self.copyListOfItems objectAtIndex:indexPath.row];
cell.codeLabel.text = code.description;
Error:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[ICD9Disease objectForKey:]: unrecognized selector sent to instance 0x1be6e0'

You are getting the error because you are asking for an object, but you're trying to set a string, in the line:
NSString *value = [dictionary objectForKey:#"name"];
Since you're getting a string, not an object, what you need to use is valueForKey:
NSString *value = [dictionary valueForKey:#"name"];

It looks like you're expecting the fetch request to return dictionaries, but it's actually returning instances of the class ICD9Disease.

Related

NSInvalidArgumentException when using a value extracted from JSON data

I am trying to retrieve value for id:
{"id":1,"name":"XYZ"}
When I use:
NSString *jsonData = [[NSString alloc] initWithContentsOfURL:[NSURL URLWithString:url]];
NSArray * myPeople = [jsonData JSONValue];
NSString *name = [[NSString alloc] init];
NSDictionary *person = [myPeople objectAtIndex:[indexPath row]];
name = [NSString stringWithString:[person valueForKey:#"id"]];
name = [name stringByAppendingString:#". "];
name = [name stringByAppendingString:[person valueForKey:#"name"]];
name = [name stringByAppendingString:[person valueForKey:#"id"]];
cell.textLabel.text = name;
I get the following error:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException'
reason: '-[NSCFNumber length]: unrecognized selector sent to instance 0x4e7f8b0
How can I fix this?
You are calling both stringWithString: and stringByAppendingString: but then passing in an NSNumber
You need to get the string value of the NSNumber
[[person valueForKey:#"id"] stringValue];
or use a format like:
name = [NSString stringWithFormat:#"%#%#", name, [person valueForKey:#"id"]];
I would also consider changing the structure slightly to make it easier to follow like this:
NSDictionary *person = [myPeople objectAtIndex:[indexPath row]];
NSString *personName = [person valueForKey:#"name"];
NSSNumber *personId = [person valueForKey:#"id"];
NSString *name = [NSString stringWithFormat:#"%#. %# %#", personId, personName, personId];
For sorting you want to make sure you are not pulling that data every time you set up a cell (looks like you are) or it will be a terrible experience.
I'm sure someone can point you to a better way of sorting but the quickest thing I can think of is
NSArray *myPeople = [[jsonData JSONValue] sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
return [[obj1 objectForKey:#"id"] compare:[obj2 objectForKey:#"id"]];
}]

Having Problems With UISearchBar in UITableViewController

I am trying to add a UISearchBar to my UITableView.
This is the method they use to search:
- (void) searchTableView {
NSString *searchText = searchBar.text;
NSMutableArray *searchArray = [[NSMutableArray alloc] init];
for (NSDictionary *dictionary in listOfItems)
{
NSArray *array = [dictionary objectForKey:#"Countries"];
[searchArray addObjectsFromArray:array];
}
for (NSString *sTemp in searchArray)
{
NSRange titleResultsRange = [sTemp rangeOfString:searchText options:NSCaseInsensitiveSearch];
if (titleResultsRange.length > 0)
[copyListOfItems addObject:sTemp];
}
[searchArray release];
searchArray = nil;
}
But I don't have a dictionary, I just want to search in my array 'exerciseArray' which is init like this:
NSString *path = [[NSBundle mainBundle]pathForResource:#"data" ofType:#"plist"];
NSMutableArray *rootLevel = [[NSMutableArray alloc]initWithContentsOfFile:path];
self.exerciseArray = rootLevel;
[rootLevel release];
When I NSLog it, I get:
exerciseArray: (
{
exerciseName = "Balance Board";
},
{
exerciseName = "Barbell Seated Calf Raise";
},
{
exerciseName = "Calf Press On The Leg Press Machine";
},
{
exerciseName = "Calf Raises- With Bands";
},
So can anyone help me modify the search method to fit the array I have? It seems to have a key in it.
I tried this but it did not work and crashed at line NSRange titleResultsRange = [sTemp rangeOfString:searchText options:NSCaseInsensitiveSearch];
with error *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFDictionary rangeOfString:options:]: unrecognized selector sent to instance 0x2d6450
- (void) searchTableView {
NSString *searchText = searchBar.text;
NSLog(#"exerciseArray: %#", exerciseArray);
for (NSString *sTemp in listOfItems)
{
if (sTemp) {
NSRange titleResultsRange = [sTemp rangeOfString:searchText options:NSCaseInsensitiveSearch];
if (titleResultsRange.length > 0)
[copyListOfItems addObject:sTemp];
}
}
}
Looks like you have an array of dictionaries with one key/value pair in each dictionary (exerciseName). so for your dataset, it should be this:
for (NSDictionary *dictionary in exerciseArray)
{
NSArray *array = [dictionary objectForKey:#"exerciseName"];
[searchArray addObjectsFromArray:array];
}
...
If you post your VC code related to the array and also your tableview datasource methods, I have can modify it and show you what you need to do.
For searching from table view i have tried this and i got success hope it will help you......
-(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
self.searching=NO;
NSString *originalString;
[self.filteredProductArray removeAllObjects];
for (int i=0; i<self.exerciseArray.count; i++)
{
originalString=[[[self.exerciseArray objectAtIndex:i] objectForKey:#"exerciseName"] lowercaseString];
if (!([originalString rangeOfString:[searchText lowercaseString]].location==NSNotFound))
{
[self.filteredProductArray addObject:[self.exerciseArray objectAtIndex:i]];
}
}
if ([searchText isEqual:#""])
{
self.searching=NO;
}
[self.tableView reloadData];
}
I believe NSPredicates are good way to search in arrays.. You can refer to this link.. Using NSPredicate to filter an NSArray based on NSDictionary keys

iPhone/iPad - Problem with Copy values of NSArray into NSMutableArray?

This code is the search code
- (void) searchTableView {
NSLog(#"4");
NSString *searchText = searchBar.text;
NSMutableArray *searchArray = [[NSMutableArray alloc] init];
for (NSDictionary *dictionary in listOfItems)
{
NSArray *array = [dictionary objectForKey:#"Countries"];
[searchArray addObjectsFromArray:array];
}
for (NSString *sTemp in searchArray)
{
NSRange titleResultsRange = [sTemp rangeOfString:searchText options:NSCaseInsensitiveSearch];
if (titleResultsRange.length > 0)
[copyListOfItems addObject:sTemp];
}
//NSLog(#"Count - %d",[copyListOfItems count]);
[searchArray release];
searchArray = nil;
}
I want to implement this type of search in my array but i am getting error in below line.
[searchArray addObjectsFromArray:array];
when control comes on this line application shutdown every time can any one help me ?
Thanks
That line will give you an error only if array has nothing in it(nil value).
So check what is the value of array using nslog.

NSMutableDictionary confused over how to use keys with certain code?

I'm getting data from a database and I need to add the string field value and the record id.
However, I need this to work with some existing code...
I'm replacing this (see code below) and getting data from my database.
NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:path];
self.allCategories = dict;
[dict release];
This is the file it loads...
But needs to work with these key and value search functions.
- (void)resetSearch {
NSMutableDictionary *allCategoriesCopy = [self.allCategories mutableDeepCopy];
self.Categories = allCategoriesCopy;
[allCategoriesCopy release];
NSMutableArray *keyArray = [[NSMutableArray alloc] init];
[keyArray addObject:UITableViewIndexSearch];
[keyArray addObjectsFromArray:[[self.allCategories allKeys]
sortedArrayUsingSelector:#selector(compare:)]];
self.keys = keyArray;
[keyArray release];
}
.
- (void)handleSearchForTerm:(NSString *)searchTerm {
NSMutableArray *sectionsToRemove = [[NSMutableArray alloc] init];
[self resetSearch];
for (NSString *key in self.keys) {
NSMutableArray *array = [Categories valueForKey:key];
NSMutableArray *toRemove = [[NSMutableArray alloc] init];
for (NSString *name in array) {
if ([name rangeOfString:searchTerm
options:NSCaseInsensitiveSearch].location
== NSNotFound)
[toRemove addObject:name];
}
if ([array count] == [toRemove count])
[sectionsToRemove addObject:key];
[array removeObjectsInArray:toRemove];
[toRemove release];
}
[self.keys removeObjectsInArray:sectionsToRemove];
[sectionsToRemove release];
[table reloadData];
}
Keep getting an error from this code...
NSDictionary *arrayTmp= [[NSDictionary alloc] init];
... loop records
int cid = sqlite3_column_int(statementTMP, 0);
NSString *category = [[NSString alloc]
initWithUTF8String:(char *)sqlite3_column_text(statementTMP, 1)];
[arrayTmp setObject:category forKey:[NSString stringWithFormat:#"%i", cid]];
Error caused by line above
* Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSCFString count]: unrecognized selector sent to instance 0x4d4c500' * Call stack at first throw *
... end loop
self.allCategories = arrayTmp;
[arrayTmp release];
The error message says you are sending 'count' to an instance of NSString.
My guess is that the plist at 'path' (the plist file) has a string as one of the values. As you iterate through 'Categories' you expect each value to be an array (i.e. 'NSMutableArray *array = [Categories valueForKey:key];') and send that value a 'count' message.
One of the objects you expect to be an array is a string.
setValue is key-value coding method. You should use setObject:forKey: instead.
arrayTmp should be inited with [[NSMutableDictionary alloc] init].
First of all, you're using wrong method:
[arrayTmp setValue:category forKey:[NSString stringWithFormat:#"%i", cid]];
which method used for key-value coding (you can find more about KVO here).
The method you're looking for is:
[arrayTmp setObject:category forKey:[NSString stringWithFormat:#"%i", cid]];
Moreover, you should NSMutableDictionary. The NSDictionary you're using does not support mutation. (you can find more info on NSMutableDictionary here).
Cheers,
Pawel

NSCFString countByEnumeratingWithState:objects:count: ERROR while searching NSMutableArray

I have the following situation where
I have an NSMutableArray filled with an xml file which I want to search.
When I enter something in the search field I get this Error:
-[NSCFString countByEnumeratingWithState:objects:count:]: unrecognized selector sent to instance 0x5b388b0
What does it means and how can I fix it??
I suppose the error is somewhere around here.
- (void)searchTableView{
searchedList = [[NSMutableArray alloc] init];
NSLog(#"new list %#", searchedList);
NSString *searchText = searchBar.text;
NSMutableArray *searchArray = [[NSMutableArray alloc] init];
for (NSDictionary *dictionary in list) {
NSArray *array = [dictionary objectForKey:#"TITLE"];
[searchArray addObjectsFromArray:array];
}
for (NSString *TempArray in searchArray) {
NSRange titleResults = [TempArray rangeOfString:searchText options:NSCaseInsensitiveSearch];
if (titleResults.length > 0)
[searchedList addObject:TempArray];
}
[searchArray release];
searchArray = nil;
}
it means you are calling a method designed for an NSArray (countByEnumeratingWithState:objects:count on a NSString.
I don't know ifthis code is copy/paste from yours, but if so, at the end where you use [searchList addObject:TempArray] you don't have an object named searchList.
Also, work on your naming conventions. big time.