About UISearchBar:textDidChange of predicateWithFormat - iphone

I have a question,I don't know why Method 2 can't get value ?
Method 1:can get value!
-(void) searchBar:(UISearchBar *) searchBar textDidChange:(NSString *)searchText{
NSString *firstName = #"55566666666";
AllMainEventRows3 = [AllMainEventRows mutableCopy];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF contains[cd] %#",firstName];
NSArray *filteredArray = [AllMainEventRows3 filteredArrayUsingPredicate:predicate];
NSLog(#"filteredArray: %#", filteredArray);
}
LOG:
filteredArray: (
{
JoinSuccess = 55566666666;
bmabout = "";
bmaddr = "\U53f0\U5317\U5e02\U9752\U5cf6\U6771\U8def99\U865f10F-6";
})
Method 2:can't get value!
-(void) searchBar:(UISearchBar *) searchBar textDidChange:(NSString *)searchText{
AllMainEventRows3 = [AllMainEventRows mutableCopy];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF contains[cd] %#",searchText];
NSArray *filteredArray = [AllMainEventRows3 filteredArrayUsingPredicate:predicate];
NSLog(#"filteredArray: %#", filteredArray);
}
LOG:
filteredArray:(
)

textDidChange Tells the delegate that the user changed the search text is delegate method of UISearchBarDelegate and it is called whenever text is changed within the search bar, I don't think the second method would get value because delegate methods are fired automatically means you are not calling them and you can not create multiple delegate methods with same name. you could declare some custom method for that purpose.
Problems in Predicate? would refer to usage of NSPredicate

Related

object and NSPredicate

In my application i have a large table of around 12000 entries. I am displaying it on tableview. But the search bar is too slow while doing dynamic search. I have read that NSPredicate method is more permorfant then NSRange.
This is my old the code:
[self.filteredListContent removeAllObjects];
listContent = [[NSArray alloc] initWithArray:[dbAccess getAllBooks]];
for (Book *book in listContent)
{
NSRange range = [book.textBook rangeOfString:searchText options:NSCaseInsensitiveSearch];
if (range.location != NSNotFound)
{
[self.filteredListContent addObject:book];
}
}
My new code:
[self.filteredListContent removeAllObjects];
listContent = [[NSArray alloc] initWithArray:[dbAccess getAllBooks]];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF like[c] %#",searchText];
[self.filteredListContent addObject:[listContent filteredArrayUsingPredicate:predicate]];
When i try to execute this code i received this error: "Can't do regex matching on object .'"
I would do something more like...
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"%k like[c] %#",propertyIAmLookingFor,searchText];
Is your book class a string? If not then you cant use SELF like. You need to substitute the name of the property you are comparing.

NSPredicate against NSArray in iphone

How can I use NSPredicate to filter the values from array ivar against search query ? I manage to use NSPredicate against string ivar. I have one user defined class named as "User" which is used to create User from AddressBook. Here is my code
// User Defined Class named as "User"
// In User.h
#interface User : NSObject {
NSString *firstName;
NSString *lastName;
NSString *company;
UIImage *userImage;
NSArray *phoneNumberArray;
NSArray *emailArray;
NSArray *urlArray;
NSArray *addressArray;
NSString *notes;
NSString *dateOfBirth;
}
// In SearchViewController.m
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText{
// contactsArray is NSMutableArray
contactsArray = [Search searchContactsWithQuery:searchText];
NSLog(#"contactsArray count => %d",[contactsArray count]);
[contactsTableView reloadData];
}
// In Search.m
+(NSMutableArray*)searchContactsWithQuery:(NSString*)query {
NSLog(#"Query => %#",query);
NSMutableArray* predicates=[[NSMutableArray alloc] init];
// Create all predicates
NSPredicate * firstNamePredicate = [NSPredicate predicateWithFormat:#"firstName contains %#",query];
[predicates addObject:firstNamePredicate];
NSPredicate * lastNamePredicate = [NSPredicate predicateWithFormat:#"lastName contains %#",query];
[predicates addObject:lastNamePredicate];
NSPredicate * companyPredicate = [NSPredicate predicateWithFormat:#"company contains %#",query];
[predicates addObject:companyPredicate];
// Don't know how to use on array
// === START of ARRAY Predicate ====
NSPredicate *phoneNoPredicate = [NSPredicate predicateWithFormat:#"phoneNumberArray IN %#",query];
[predicates addObject:phoneNoPredicate];
NSPredicate *emailPredicate = [NSPredicate predicateWithFormat:#"emailArray contains %#",query];
[predicates addObject:emailPredicate];
NSPredicate *urlPredicate = [NSPredicate predicateWithFormat:#"urlArray contains %#",query];
[predicates addObject:urlPredicate];
NSPredicate *addressPredicate = [NSPredicate predicateWithFormat:#"addressArray contains %#",query];
// === END of ARRAY Predicate ====
NSPredicate *notesPredicate = [NSPredicate predicateWithFormat:#"notes contains %#",query];
[predicates addObject:notesPredicate];
NSPredicate *dobPredicate = [NSPredicate predicateWithFormat:#"dateOfBirth contains %#",query];
[predicates addObject:dobPredicate];
// Add predicates to array
NSPredicate *compoundPredicate = [NSCompoundPredicate orPredicateWithSubpredicates:predicates];
NSArray * filteredArray = [APP_DELEGATE.allUsersArray filteredArrayUsingPredicate:compoundPredicate];
return [NSMutableArray arrayWithArray:filteredArray];
}
phoneNumberArray,emailArray,urlArray & addressArray are used because user may have multiple entries for phone no , email, address , url like HOME , WORK, iPhone, Other etc.
How can I use predicates on array? Any kind of help is appreciated. Thanks
You are doing the correct way, but you need to create your Predicates with String values instead of passing the Objects directly.
You need to use %k instead of %# like
[NSPredicate predicateWithFormat:#"firstName contains %k",query];
Please let me know if this helps.

Sort an NSString

i have an iOS application witch have a search bar and a UITableView. when i click in the search bar for example "ta", the web services return to me all the words witch contain "at",
for example "beta","mota","at work","ebebebatbcbcb" , i would like to have just the words witch begin with "at", not all the words witch contain "at".
Thanks for your answers.
try this:
-(NSMutableArray *)array:(NSMutableArray *)array withstart:(NSString *)string{
NSPredicate *sPredicate = [NSPredicate predicateWithFormat:#"SELF beginswith[c] %#",string];
[array filterUsingPredicate:sPredicate];
return array;
}
Or other way:
NSString *prefix = #"at";
NSArray *final_array=[array objectsAtIndexes:[array indexesOfObjectsPassingTest:^(id obj, NSUInteger idx, BOOL *stop)
{
return [obj hasPrefix:prefix];
}]];
NSPredicate is the way to go:
NSString *searchTerm = #"ta";
NSArray *matchingKeywords = [result filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"SELF beginswith[cd] %#",searchTerm]];
Heres a simple answer
NSString *prefix = #"at";
[array objectsAtIndexes:[array indexesOfObjectsPassingTest:^BOOL(NSString *string, NSUInteger idx, BOOL *stop) {
return [string hasPrefix:prefix];
}]];
Sounds like a job for NSPredicate!

NSPredicate on NSDictionary

I'm trying to make sections in a table view based on the alphabet and sort my entries alphabetically under these sections.
I have collected the first letter in every entry of bandsArray in bandsArrayIndex and I'm now trying to use NSPredicate to count how many of each letter there are.
I'm doing this by following this guide.
They are using an NSArray and I'm using an NSDictionary and can't seem to get it to work. Can anyone help me out?
The application crashes when trying to show the view with the table view in it.
In Debugger Console the following error is shown:
* Terminating app due to uncaught exception
'NSInvalidArgumentException', reason:
'Can't do a substring operation with
something that isn't a string
This is my code
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSString *alphabet = [bandsArrayIndex objectAtIndex:section];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF beginswith[c] %#", alphabet];
NSArray *letters = [bandsArray filteredArrayUsingPredicate:predicate];
return [letters count];
}
EDIT: This is my bandsArray.
The header
NSMutableArray *bandsArray;
#property (nonatomic, retain) NSMutableArray* bandsArray;
The implementation
// set array from plist
NSString *path = [[NSBundle mainBundle] pathForResource:#"Bands" ofType:#"plist"];
NSMutableArray* tmpArray = [[NSMutableArray alloc] initWithContentsOfFile:path];
self.bandsArray = tmpArray;
// sort array after name ascending
NSSortDescriptor *nameSorter = [[NSSortDescriptor alloc] initWithKey:#"name" ascending:YES selector:#selector(caseInsensitiveCompare:)];
[bandsArray sortUsingDescriptors:[NSArray arrayWithObject:nameSorter]];
Do you mean that bandsArray is an array of dictionaries? If so, and assuming each dictionary has a name key, you should be able to change the predicate to something like #"SELF.name beginswith[c] %#".
If, on the other hand, bandsArray is actually a dictionary itself, maybe you want to do [[bandsArray allKeys] filteredArrayUsingPredicate...].
#import <Foundation/Foundation.h>
// clang -framework Foundation Siegfried.m
int
main() {
NSArray *arr = #[
#{#"1" : #"Fafner"},
#{#"1" : #"Fasolt"}
];
NSPredicate *p = [NSPredicate predicateWithFormat: #"SELF['1'] CONTAINS 'e'"];
NSArray *res = [arr filteredArrayUsingPredicate:p];
NSLog(#"Siegfried %#", res);
return 0;
}
Sorry, I didnt notice you had a NSArray of NSDictionaries.
Read this thread: Using NSPredicate to filter an NSArray based on NSDictionary keys
When you use NSDictionary, you should check by its Key... I'm not sure you're using the right approach!
I would do something like:
#implementation Word : NSObect {
NSString *title;
}
then I would create a NSArray of Words and filter on them with:
#"title beginswith[c] %#"

NSCompoundPredicate fails to match

I'm building a NSPredicate using the code below for an iPhone app. The logging shows the prediate to be: location CONTAINS "head" AND shape CONTAINS "oval" AND texture CONTAINS "bumpy" AND colour CONTAINS "red"
I get no results. If I limit the predicate to a single item it will work, more than 1 fails.
Can anyone tell me why?
Many thanks
NSMutableArray *subPredicates = [[NSMutableArray alloc] init];
for (Ditem in self.tableDataSource) {
NSString *Title = [Ditem valueForKey:#"Title"];
NSString *Value = [Ditem valueForKey:#"Value"];
if([[Value lowercaseString] isEqualToString: #"all"]){
Value = #"";
}
else{
NSPredicate *p = [NSComparisonPredicate predicateWithLeftExpression:[NSExpression expressionForKeyPath:[Title lowercaseString]] rightExpression:[NSExpression expressionForConstantValue:[Value lowercaseString]] modifier:NSDirectPredicateModifier type:NSContainsPredicateOperatorType options:0];
[subPredicates addObject:p];
}
}
NSPredicate *predicate = [NSCompoundPredicate andPredicateWithSubpredicates:subPredicates];
NSLog(#"predicate: %#", predicate);[self.fetchedResultsController.fetchRequest setPredicate:predicate];
Your predicate is requiring that all of the values in your filterable objects be strings. Is that correct?
Also, I would simplify your subpredicate creation to:
NSPredicate * p = [NSPredicate predicateWithFormat:#"%K CONTAINS %#", [Title lowercaseString], [Value lowercaseString]];