How to use searchDisplayController with objects of class - iphone

I have a class, with some objects (Title, price, modifier), And I have an NSArray of objects of this class.
I load this NSArray into UITableView. How can I use searchDisplayController?
I can't understand.. array have only addresses (to objects in my class) and how i can sort it by predicate?

I can explain with an example
Let consider my code is like below
Without NSPredicate
NSMutableArray *oldSkoolFiltered = [[NSMutableArray alloc] init];
for (Book *book in bookshelf) {
if ([book.publisher isEqualToString:#"Apress"]) {
[oldSkoolFiltered addObject:book];
}
}
Applied NSPredicate
NSPredicate *predicate =
[NSPredicate predicateWithFormat:#"publisher == %#", #"Apress" ];
NSArray *filtered = [bookshelf filteredArrayUsingPredicate:predicate];

I think you have forgot the type casting of the array to the class name.
Try to do like this
cell.textLabel.text=((ClassName *)[arrOfObjects objectAtIndex:indexPath.row]).Title;
and for predicate i will suggest you to go through this example

Related

How to sort an NSArray full of EKCalendars by the title

I've got a NSArray with a bunch of EKCalendar Objects in it. I need to sort them alphabetically. I'm new to selectors but I think I need something like...
NSArray *array = [otherArray sortedArrayUsingSelector:#selector('localizedCaseInsensitiveCompare:title')];
Cheers
You cannot do it that way. Instead do the following:
NSArray *sortedArray = [array sortedArrayUsingComparator: ^(id obj1, id obj2) {
EKCalendar *cal1 = (EKCalendar *)obj1;
EKCalendar *cal2 = (EKCalendar *)obj2;
return [cal1.title localizedCaseInsensitiveCompare:cal2.title];
}];
Edit - an explanation:
-sortedArrayUsingComparator takes what is called a 'block' (an inline function) that must return an NSComparisonResult. All the hard work is done for you, as your block is run for as many pairs of objects as is needed to establish the correct order. Then all this does is cast each object type to an EKCalendar and then compare the two titles. You can adapt this to work for any type of object.
This should do the trick:
NSMutableArray *sortDescriptors = [NSMutableArray array];
NSSortDescriptor *sortByTitleAsc = [[[NSSortDescriptor alloc] initWithKey:#"title" ascending:YES] autorelease];
[sortDescriptors addObject:sortByTitleAsc];
NSArray *arraySortedByTitle = [otherArray sortedArrayUsingDescriptors:sortDescriptors];
No, you don't want to use a selector, you want to use a key path, which requires a sort descriptor. You can't append an arbitrary property name to a selector name. The selector must exactly match the method name. Otherwise you just get nothing (nil/NULL/0) for the selector.
id sortedArray = [array sortedArrayUsingDescriptors:[NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:#"title" ascending:YES]]];
For the sake of completeness and and timeliness, here’s the Swift 4 version:
let store = EKEventStore()
let calendars = store.calendars(for: .event)
let calendarsSorted = calendars.sorted { $0.title.localizedCaseInsensitiveCompare($1.title) == ComparisonResult.orderedAscending }
By the way, please don’t forget to request access to the store by calling store.requestAccess(to:completion:) before accessing the store’s data.

NSPredicate filter

I have never used NSPredicate before so please bear with me. I have an array which have a boolean key as "isChecked". I want to filter the array which have the boolean set as "YES", any idea how can I do it, plus if there is any reference to such query methods that would be nice to have it handy.
Thanks
//NSArray * myArray is your array
//containing your objects that each have an isChecked property
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"isChecked == YES"];
NSArray *filteredArray = [myArray filteredArrayUsingPredicate:predicate];
// filteredArray is the new array that only contains your checked items
Cheers
First you create an NSPredicate instance. In this case, we'll use -initWithFormat:.
NSPredicate *predicate = [[NSPredicate alloc] initWithFormat:#"isChecked == YES"];
Then we'll use the -filteredArrayUsingPredicate: method on NSArray to get an NSArray of all the objects which match the predicate.
NSArray *filteredArray = [originalArray filteredArrayUsingPredicate:predicate];

fetching objects from core data not in a set

I'm trying to fetch objects from core data that are not in a given set, but I haven't been able to get it to work.
For instance, suppose that we have a core data entity named User, which has a few attributes such as userName, familyName, givenName, and active. Given an array of strings representing a set of usernames, we can easily fetch all the users corresponding to that list of usernames:
NSManagedObjectContext *moc = [[NSManagedObjectContext alloc] init];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"User"
inManagedObjectContext:moc];
[request setEntity:entity];
NSArray *userNames = [NSArray arrayWithObjects:#"user1", #"user2", #"user3", nil];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"userName IN %#", userNames];
[request setPredicate:predicate];
NSArray *users = [moc executeFetchRequest:request error:nil];
However, I want to fetch the complement of that set, i.e., I want all the users in core data that don't have the usernames specified in the userNames array. Does anyone have an idea how to approach this issue? I thought it would be simple enough to add a "NOT" in the predicate (i.e., "userName NOT IN %#"), but Xcode throws an exception saying the predicate format could not be parsed. I also tried using the predicate builder available for fetch requests with no luck. The documentation wasn't particularly helpful either. Suggestions? Comments? Thanks for all your help :)
In order to find the objects that aren't in your array, all you have to do is something like this:
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"NOT (userName IN %#)", userNames];
That should return a request of all the objects without the ones you specified
I am not strong at core data/objective-c but the predicate should be like the following statement;
[predicateFormat appendFormat:#"not (some_field_name in {'A','B','B','C'})"];
An example:
NSMutableString * mutableStr = [[NSMutableString alloc] init];
//prepare filter statement
for (SomeEntity * e in self.someArray) {
[mutableStr appendFormat:#"'%#',", e.key];
}
//excluded objects exist
if (![mutableStr isEqual:#""])
{
//remove last comma from mutable string
mutableStr = [[mutableStr substringToIndex:mutableStr.length-1] copy];
[predicateFormat appendFormat:#"not (key in {%#})", mutableStr];
}
//...
//use this predicate in NSFetchRequest
//fetchRequest.predicate = [NSPredicate predicateWithFormat:predicateFormat];
//...
Here's another useful example, showing how to take a list of strings, and filter out any which DON'T start with the letters A-Z:
NSArray* listOfCompanies = [NSArray arrayWithObjects:#"123 Hello", #"-30'c in Norway", #"ABC Ltd", #"British Rail", #"Daily Mail" #"Zylophones Inc.", nil];
NSPredicate *bPredicate = [NSPredicate predicateWithFormat:#"NOT (SELF MATCHES[c] '^[A-Za-z].*')"];
NSArray *filteredList = [listOfCompanies filteredArrayUsingPredicate:bPredicate];
for (NSString* oneCompany in filteredList)
NSLog(#"%#", oneCompany);
I use this kind of NSPredicate when I'm populating a UITableView with an A-Z index, and want an "everything else" section for items which don't start with a letter.

Extracting strings from a NSArray of objects, based on a array of NSStrings

OK, this is a bit obscure, but it's giving me a headache.
If you have an array of strings
{#"1", #"2", #"4"}
And you have a array of Recipe objects
{ {recipe_name:#"Lasagna", recipe_id:#"1"}
{recipe_name:#"Burger", recipe_id:#"2"}
{recipe_name:#"Pasta", recipe_id:#"3"}
{recipe_name:#"Roast Chicken", recipe_id:#"4"}
{recipe_name:#"Sauerkraut", recipe_id:#"5"}
}
How would I, using the first array, create an array like this:
{#"Lasagna", #"Burger", #"Roast Chicken"}
In ither words, it is taking the numbers in the first array and creating an array of recipe_names where the recipe_id matches the numbers...
Use an NSPredicate to specify the type of objects you want, then use -[NSArray filteredArrayUsingPredicate:] to select precisely those objects:
NSArray *recipeArray = /* array of recipe objects keyed by "recipe_id" strings */;
NSArray *keyArray = /* array of string "recipe_id" keys */;
NSPredicate *pred = [NSPredicate predicateWithFormat:#"recipe_id IN %#", keyArray];
NSArray *results = [recipeArray filteredArrayUsingPredicate:pred];
NSPredicate uses its own mini-language to build a predicate from a format. The format grammar is documented in the "Predicate Programming Guide."
If you are targeting iOS 4.0+, a more flexible alternative is to use -[NSArray indexesOfObjectsPassingTest:]:
NSIndexSet *indexes = [recipeArray indexesOfObjectsPassingTest:
^BOOL (id el, NSUInteger i, BOOL *stop) {
NSString *recipeID = [(Recipe *)el recipe_id];
return [keyArray containsObject:recipeID];
}];
NSArray *results = [recipeArray objectsAtIndexes:indexes];
Your array of recipe objects is basically a dictionary:
NSDictionary *recipeDict =
[NSDictionary dictionaryWithObjects:[recipes valueForKey:#"recipe_name"]
forKeys:[recipes valueForKey:#"recipe_id"]];
And on a dictionary you can use the Key-Value Coding method:
NSArray *result = [[recipeDict dictionaryWithValuesForKeys:recipeIDs] allValues];
Assuming that your Recipe objects are key-value compliant (which they almost always are) you can use a predicate like so:
NSArray *recipes= // array of Recipe objects
NSArray *recipeIDs=[NSArray arrayWithObjects:#"1",#"2",#"3",nil];
NSPredicate *pred=[NSPredicate predicateWithFormat:#"recipe_id IN %#", recipeIDs];
NSArray *filterdRecipes=[recipes filteredArrayUsingPredicate:pred];
NSArray *recipeNames=[filterdRecipes valueForKey:#"recipe_name"];

Use NSPredicate to filter by object attribute

I have a mutable array of custom objects. I want to filter that array by attribute of the object, for example myObject.attributeOne.
How can I create the NSPredicate to use with
[myArrayOfObjects filterUsingPredicate:<the_predicate>]
Use it in this way:
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"FriendStatus == 1"];
NSMutableArray *filtered = [MessageArray filteredArrayUsingPredicate:predicate];