On Mar 13, 2011, at 1:51 AM, Indragie Karunaratne wrote: > Andreas, > > That predicate syntax (and block predicates) won't work in my case because > I'm using them in a Core Data NSFetchRequest. This is true only if you use a sqlite store - but this is also most likely ;)
If you were not using SQLite, this simple predicate should have worked with a fetch request: NSPredicate* pred = [NSPredicate predicateWithFormat:@"ALL %@ IN {attr0, attr1}", terms]; where terms is an array (or better a set) of strings, and attr0 and attr1 are key paths for attributes of the managed object. Here, the values for the attributes for each candidate of the managed objects are used in the predicate. The predicate becomes true only if all search terms are found in any of the values of the attributes. You may have meant it the other way around, then the predicate would become: NSPredicate* pred = [NSPredicate predicateWithFormat:@"ALL {attr0, attr1} IN %@", terms]; Anyway, as you already found out, this predicate would not work with a sqlite store type. The reason is, that a *fetch* predicate must be mapped to an equivalent sqlite query - which is not always possible. The error isn't a parser error, though. It is actually an Invalid Argument Exception whose reason is "unsupported predicate" which is thrown when you try to *execute the fetch*. So, the task is to find another form of the predicate which will work with the sqlite store. > I did, however, manage to solve this issue by using subpredicates: This is fine, however I'm not completely confident that your compound predicate (below) actually expresses your original intent. Consider, the prediacte All tems IN attributes is equivalent to (term_0 IN attributes) AND (term_1 IN attributes) ... AND (term_n IN attributes) So the code for this would look like this: NSMutableArray* subPredicates = [[NSMutableArray alloc] initWithCapacity:[terms count]]; for (NSString* term in terms) { NSPredicate* p = [NSPredicate predicateWithFormat:@"%@ IN {attr0, attr1}", term]; [subPredicates addObject:p]; } NSPredicate* pred = [NSCompoundPredicate andPredicateWithSubpredicates:subPredicates]; [subPredicates release], subPredicates = nil; [fetchRequest setPredicate:pred]; Regards Andreas > > NSPredicate *basePredicate = [NSPredicate predicateWithFormat:@"(name > CONTAINS[cd] $QUERY) OR (artist.name CONTAINS[cd] $QUERY)"]; > NSMutableArray *andPredicates = [NSMutableArray array]; > for (NSString *term in terms) { > NSDictionary *substitution = [NSDictionary > dictionaryWithObjectsAndKeys:term, @"QUERY", nil]; > NSPredicate *andPredicate = [basePredicate > predicateWithSubstitutionVariables:substitution]; > [andPredicates addObject:andPredicate]; > } > NSPredicate *finalPredicate = [NSCompoundPredicate > andPredicateWithSubpredicates:andPredicates]; > > On 2011-03-12, at 6:17 AM, Andreas Grosam wrote: > >> >> On Mar 12, 2011, at 3:36 AM, Indragie Karunaratne wrote: >> >>> I have an NSManagedObject that has the following string attributes: >>> >>> artist, albumArtist, composer, comments, and lyrics >>> >>> I need to write an NSPredicate that will take an array of search terms, and >>> check if all of the above string attributes COMBINED contains every term in >>> the search term array. I tried the following predicate format: >>> >>> NSArray *searchTerms = [NSArray arrayWithObjects:@"testing", @"search", >>> nil]; >>> NSPredicate *predicate = [NSPredicate predicateWithFormat:@"ALL %@ IN { >>> artist, albumArtist, composer, comments, lyrics }", searchTerms]; >>> >>> This triggered a parsing error and would not run. Is there any way I can do >>> this in an NSPredicate, aside from creating a "search string" attribute in >>> my data model containing a concatenated string of the above attributes? >> >> >> You should not include the object where the predicate is run against into >> the parameters of the format string. Otherwise, you would get a constant >> expression, rather a predicate. >> >> Furthermore, when specifying an embedded string-list you need to quote the >> string elements. >> >> This should work then: >> >> NSArray* terms = ... >> NSPredicate* pred = [NSPredicate predicateWithFormat:@"ALL self IN >> {'artist', 'albumArtist', 'composer', 'comments'}"]; >> >> BOOL test = [pred evaluateWithObject:terms]; >> >> >> Note: you can use a ^block for the predicate as well. >> >> >> Regards >> Andreas_______________________________________________ >> >> Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) >> >> Please do not post admin requests or moderator comments to the list. >> Contact the moderators at cocoa-dev-admins(at)lists.apple.com >> >> Help/Unsubscribe/Update your Subscription: >> http://lists.apple.com/mailman/options/cocoa-dev/cocoadev%40indragie.com >> >> This email sent to cocoa...@indragie.com > _______________________________________________ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com