CoreData fetch request NSPredicate not working - ios

I've added a new bool property to an entity in my CoreData model and migrated the existing data to the new model. I now want to fetch only the data with a bool value of false. I tried everything suggested here on StackOverflow but I could not find an answer to my problem.
I tried following predicates:
let predicate = NSPredicate(format: "%K == %i", #keyPath(Tag.isWrite), false)
fetchRequest.predicate = predicate
let predicate = NSPredicate(format: "isWrite == 0")
fetchRequest.predicate = predicate
let predicate = NSPredicate(format: "isWrite == %#", NSNumber(value: false))
fetchRequest.predicate = predicate
The default value for the migrated model is false for isWrite. When I don't apply the predicate and set a breakpoint before displaying my data I can clearly see that isWrite is false in the debugger. When I apply the predicate I don't get any data.
Am I missing something out?

There appears to be a problem in CoreData with attribute names beginning with “is...”. Try changing the name for your attribute.

Related

Unable to fetch from coreData using Predicate as String?

I am unable to fetch data using a string as a direct argument to NSPredicate. Is there any difference between these two,
//Working case
fetchRequest.predicate = NSPredicate(format: "role == %#","GK")
In the above case, I am able to fetch the data with the predicate.
//Not Working
predicateString = String(format:"role == %#","GK")
fetchRequest.predicate = NSPredicate(format: predicateString)
Here I am unable to fetch the data.
The only difference between the above two cases is that I'm using a String variable to define the predicate. What is wrong here?
When the %# is replaced with a string variable when instantiating a NSPredicate the string variable is automatically surrounded by quotes so in your example the predicate becomes role == 'GK'
If you want to use String(format:...) you need to add the quotes yourself but in my opinion it's better to use NSPredicate(format:...) directly instead to avoid issues like this.
Format of NSPredicate is as following, where it expects a format, and format contains equaliser.
NSPredicate(format: <String>, <args: CVarArg...>)
let predicate1 = NSPredicate(format: "role == %#", "GK")
Here, if you will check the predicate1.predicateFormat, then you will get:
"role == \"GK\"",
which equilise role with string "GK" and return result in array.
But for,
let predicateString = String(format:"role == %#","GK")
let predicate2 = NSPredicate(format: predicateString)
You replaced the equaliser with simple string, which fails to return anything. You can check with predicate1.predicateFormat which will return:
"role == GK"
Here you can use "role == 'GK'" if you want to use string.
Hope it will help.

CoreData fetching all one-to-many relationship

I have two classes, Session and Course, with a one-to-many relationship between a session and courses. I'm trying to fetch all of a session's courses using an NSPredicate. The predicates I have tried throw errors.
let fetchRequest: NSFetchRequest<Course> = Course.fetchRequest()
guard let startDate = session.startDate else {
fatalError("Attempting to fetch courses for session without a start date")
}
let sessionPredicate = NSPredicate(format: "ALL %K == %#",
#keyPath(Course.session.startDate),
"\(startDate)")
fetchRequest.predicate = sessionPredicate
If you want to find all courses whose session has a given start date it's easier:
let sessionPredicate = NSPredicate(format: "session.startDate == %#", startDate)
NSManagedObject provides full KVC support

coredata fetch with predicate for object relation using swift

I'm trying to perform a fetch for an entity in coreData. This entity has a one to one relation with another entity. I want to only get the items in the first entity that have a relation to a particular item in the second entity. I'm trying this predicate which I know is incorrect:
let fetchRequest: NSFetchRequest<ItemA> = NSFetchRequest(entityName: "ItemA")
fetchRequest.predicate = NSPredicate(format: "itemA.itemB.itemBId == %d", Int(itemB.itemBId))
Currently you are using itemA.itemB.itemBId , here you are using a new entity of itemA , where as you dont need to give its name, since this predicate will be applied on itemA entity, so either you can use only itemB.itemBId inside predicate or you can use SELF.itemB.itemBId (I am not sure about SELF or self, obviously you can look it up).
So I think you can get the items of type itemA whose relation itemB has an id of itemBId like this:
let fetchRequest: NSFetchRequest<ItemA> = NSFetchRequest(entityName: "ItemA")
fetchRequest.predicate = NSPredicate(format: "itemB.itemBId == %d", Int(itemB.itemBId))

Field '___recordID' is not marked queryable

I try to download all record with a specific recordType that recordID is not matches with a certain one.
But I get an error. Any idea? I thought I can mark as queryable only manually added fields.
<CKError 0x15df2a10: "Invalid Arguments" (12/2015); server message = "Field '___recordID' is not marked queryable"; uuid = ECDD0C97-550F-4DD5-942D-AF4DF8917EEB; container ID = "iCloud.com.kukodajanos.Movie-Buffs">
let query = CKQuery(recordType: "UserSetting", predicate: NSPredicate(format: "recordID != %#", CKRecordID(recordName: loggedInUserRecordName!)))
I found. possible to add metaindexes as well.
You only need to manually set the Query index on ID if you choose NOT to use a predicate with your query. If you use a predicate on any self defined field name such as:
e.g.
let predicate = NSPredicate(format: "UserRecordID = %#", selectedUser!.userRecordID!.recordName)
let query = CKQuery(recordType: recordType, predicate: predicate)
you will not experience this issue.

Predicate for filtering by specific managed object - Swift

I have one to many relationship in my core data model ('Client'<-->>Assessment') and in my assessment tableview I am currently filtering assessments by client name.
func assessmentFetchRequest() -> NSFetchRequest {
let fetchRequest = NSFetchRequest(entityName: "Assessment")
let sortDescriptor = NSSortDescriptor(key: "nsDateOfAssessment", ascending: false)
fetchRequest.sortDescriptors = [sortDescriptor]
fetchRequest.predicate = NSPredicate(format: "client.name == %#", self.client.name)
return fetchRequest
}
I would like to know how, or if its possible, to filter by the specific managed object instead of an attribute of the managed object ('name' in this case). I've tried changing my predicate to this:
fetchRequest.predicate = NSPredicate(format: "client.objectID == %#", self.client.objectID)
but I just get a crash with an uncaught exception.
I'm wanting to change this because it seems bad practice to filter by name since two clients may have the same name and therefore the same filter results.
So I am going to guess that for you sort descriptor the key name of 'nsDateOfAssessment' is not the actual name of the core data attribute. The key should be the actual name of attribute. Also, I wouldn't say that filtering by first name is bad practice. Perhaps add an additional param to your predicate that can help pinpoint the correct items. Of course, if you are storing a unique identifier for each entity, it would be a cleaner way to go about it.

Resources