I am doing a CloudKit query, in which I exclude any entities with the 'creatorUserRecordID' equal to any Id's stored within an array called matchesArray, I have done this by using NSPredicate (along with other custom predicates):
let predicate4:NSPredicate = NSPredicate(format: "creatorUserRecordID IN %#", matchesArray:[Array])
However, I am getting the following error:
Argument labels '(format:, matchesArray:)' do not match any available overloads.
Does anyone know how to fix this, and not query entitles which creators ID is stored within the matches array?
I think you were trying to write this,
let predicate4:NSPredicate = NSPredicate(format: "creatorUserRecordID IN %#", matchesArray)
Related
I have a Core Data entity which has an attribute called likedMovies which is a String array [String]. This is configured as a Transformable attribute.
I populate a list of IDs inside this attribute, so for example:
User entity:
name = Duncan | likedMovies = [524, 558, 721]
name = Saskia | likedMovies = [143, 558, 653]
name = Marek | likedMovies = [655, 323, 112]
I would like to write a predicate which returns all User entities where the likedMovies array contains a given value. I have tried the predicate below but it doesn't work - for the id 558, instead of returning [Duncan, Saskia] I get no entities returned.
fetchRequest.predicate = NSPredicate(format: "%# IN %#", "558", "likedMovies")
Thank you in advance for your help.
There are two issues: first, your predicate format is wrong. You cannot use %# as placeholder for attribute names; you must instead use %K:
fetchRequest.predicate = NSPredicate(format: "%# IN %K", "558", "likedMovies")
But the second problem is that transformable attributes cannot be used in predicates as part of a fetch request (for a SQLite store). One option is to use the predicate to filter the User objects in memory (after fetching them). Another option is to represent the array of IDs as a string (with suitable separator), rather than an array of strings. You can then use the CONTAINS string operator to create the predicate. But adding and removing IDs to the likedMovies will become a rather unwieldy process of string manipulation. Another option is to replace the transformable attribute with a to-many relationship. I recommend the last of these.
I'm working on Stanford CS193p's SmashTag Popularity Mentions assignment (asst. #5) and I've got everything working well. I'm working on Extra Task #3:
Loading up a lot of data by querying for an existing instance in the database, then inserting if not found over and over again, one by one (like we did in lecture), can be pretty poor performing. Enhance your application to make this more efficient by checking for the existence of a pile of things you want to be in the database in one query (then only creating the ones that don’t exist). The predicate operator IN might be of value here.
I've managed to do something like this, but not using the IN predicate operator! This is inside the perform block of my updateDatabase(with newTweets:) method: (I've called my core data entity CDTweet
if let databaseTweets = try? globalContext!.fetch(NSFetchRequest<CDTweet>(entityName: "CDTweet")) {
let databaseIDs = databaseTweets.map { $0.id! }
for twitterInfo in newTweets where !databaseIDs.contains(twitterInfo.id) {
_ = CDTweet.createCDTweet(with: twitterInfo, into: globalContext!)
}
}
As you can see, I get all the tweets in the database, get their IDs, and then only create a new tweet for internet-fetched-Twitter.Tweets whose IDs are not in the array of database tweets.
This appears to function properly (i.e., create only the new tweets), but I am very curious how the instructor imagined it would work with the IN predicate operator. Has anyone done this and can lend some insight?
Note: A number of solutions I've seen have a core data entity for the Search Term (usually called Query). I don't have this, only entities for Tweet and Mention, and I have everything working fine.
You need something like this (i assume searchIDs is an array of values you are looking for):
var searchIDs = // ... an array of IDs you are searching for
var fetchRequest = NSFetchRequest<CDTweet>(entityName: "CDTweet")
let predicate = NSPredicate(format: "id IN %#", searchIDs)
fetchRequest.predicate = predicate
databaseTweets = try? globalContext!.fetch(fetchRequest) {
// here you should only get all entries with IDs in the newTweets array
}
Details about predicates can be found here, about predicate syntax especially here
I have a coredata entity bound to a tableView with 5 columns.
I am using an array controller for managing the tableview sorting etc.
My issue is with searching using the bindings. I have a searchField bound to the ArrayController and the predicate format is set to the first column of data. Everything works fine. I can also change the predicate format in XCODE and search on a different column.
The problem I am having is knowing how the change the predicate format in my code to allow the user to search on a column of their choice...
I have attempted modifying the ArrayController as follows:
let predicate = NSPredicate(format: "projectNumber contains[cd] %#", searchBar.stringValue)
searchArrayController.filterPredicate = predicate
AND
let predicate = NSPredicate(format: "customerName contains[cd] %#", searchBar.stringValue)
searchArrayController.filterPredicate = predicate
projectNumber and customerName are attributes of my entity.
When I set the predicate this way the table data vanishes. I am able to get it to show again with fiddling of the search field but it ignores my predicate settings and only obeys the original one set in the XCODE storyboard.
StoryBoard setting is:
Predicate Format = projectNumber contains[cd] $value
thank you in advance for any help you can provide...
Add a predicate binding for each column. When you bind predicate of the search field, a binding predicate2 appears. No coding required.
I can easily get record with specific ID. If I need something specific then I can use CKQueryOperation.
I need to provide it with proper predicate, but I can't specify IDs as parameter of predicate, because it doesn't support CKRecordValue protocol. Another idea is to use CKReference, but how to write proper predicate then?
If I try to use array of Strings and evaluate agains recordID.recordName key path:
var references:[String] = IDs.map{$0.recordName}
var predicate = NSPredicate(format: "ANY recordID.recordName IN %#", references)
I get following error:
<CKError 0x17005f3b0: "Invalid Arguments" (12/1009); "Invalid predicate: recordKey (recordID.recordName) contains invalid characters">
Predicate format output:
predicate ANY recordID.recordName IN {"AFF487BE-4A7E-4F76-8185-79FA2E1EFC33", "D4D83B37-97DE-4BF2-9E43-4C5522E36DF1", "0126008A-0B42-4F95-AB31-BB13B6215475", "6DE83AD9-F307-467D-A5EF-AD2B97B8E7F7", "F701ADBF-9BE7-4F42-8CA9-44D2D0E629F8", "38C4FB60-8A65-43F9-8E1E-4C48D5B60DCD"}
Any help is appreciated.
You can use a CKFetchRecordsOperation to fetch records whose RecordIDs you already know:
let fetchRecordsOperation = CKFetchRecordsOperation(recordIDs: recordIDs)
fetchRecordsOperation.desiredKeys = desiredKeys
Init the operation with an array of the CKRecordIDs you'd like to retrieve and it will return each individual record result in the perRecordCompletionBlock and all records fetched in fetchRecordsCompletionBlock.
You can retrieve the complete records by default or just a subset of their values by setting an array of NSStrings to the desiredKeys property with the names of the fields you'd like to retrieve.
I want to filter all the posts that don't have one of the IDs in the favoritePosts array.
I tried this but it doesn't work:
[NSPredicate predicateWithFormat:#"postID IN %#",favoritesPosts_];
I get this error: 'Invalid predicate: nil RHS'
Any ideas on how to write the predicate correctly?
The array is made of a NSNumber objects and i want to filter my tableview's fetchResultController with this predicate. the Post object has a PostID attribute which is of the NSNumber type.
Maybe thats not the way to do that.. The objective is to show in the tableview which is controlled by the fetchResultsController only the posts that their ids are in the favoritesPosts_ array. So if someone has a different idea on how to do that i will appreciate it.
If favoritesPosts_ is a string array containing the post IDs, then you can very well use the predicate you have created,
predicateWithFormat:#"postID IN %#", favoritesPosts_];
But if favoritesPosts_ contains objects which have a property, say, postID, then your predicate should be,
predicateWithFormat:#"postID IN %#", [favoritesPosts_ valueForKey:#"postID"]];