CoreData fetching all one-to-many relationship - ios

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

Related

CoreData fetch request NSPredicate not working

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.

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))

Coredata nested relationships retrieving data

I have the following entities:
Orders <-->> OrderLines <<--> Products
An Order entity has an 'orderNo' attribute that has a one to many relationship with an 'orderNo' attribute in OrderLines.
The OrderLines entity has can have a many to one relationship with the Products entity.
I want to pass a customer code and retrieve all products that we currently have in the Products entity that they have ordered before.
I have tried the following predicate search to no prevail:
let pred : NSPredicate = NSPredicate(format: "orderlines.order.customer = %#", customer)
I've also tried
let pred : NSPredicate = NSPredicate(format: "ANY orderlines.order.customer = %#", customer)
I'm usually faced with an error of:
Can not map from a to-many to a to-one relationship
Any advice?
UPDATE
The code retrieving the data is:
static func repeatsList(customer: String) -> NSArray{
let ordersRequest : NSFetchRequest<Products> = Products.fetchRequest()
let pred : NSPredicate = NSPredicate(format: "ANY SELF.line.order.invoicecustomer == %#", customer)
ordersRequest.predicate=pred
do{
let repeatsArray = try GlobalHelpers.getContext().fetch(ordersRequest)
return repeatsArray as NSArray
}catch let error as NSError {
let empty : NSArray = [error]
return empty
}
}

NSPredicate for Nested Relationships (many to many) iOS

I've been struggling for several hours and thought I'd reach out to SO. In my app's data model, I have an entity, SubCategory, which has many CreatedTask, and each CreatedTask can have many User:
Say I have an User entity variable, called userObject.
I want to fetch all SubCategories, where tasks.assignees has userObject. How do I do this?
Here is what I've tried so far:
let userFetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "SubCategory")
let predicate = NSPredicate(format: "%# IN tasks.assignees", userObject)
fetchedResultsController.fetchRequest.predicate = predicate
However I am generating a nasty error:
unimplemented SQL generation for predicate.
Any help would be greatly appreciated.
Full Error Output:
Thanks to yan's help I was able to figure it out, just had to place the user object into an array.
let users: [User] = [userObject]
let predicate = NSPredicate(format: "SUBQUERY(tasks, $m, ANY $m.assignees IN %#).#count > 0", users)

NSPredicate to use with Transformable property

I have array of strings which I save in Core Data as Transformable. From json I am gettings needed strings like this:
if let mealTimes = dictionary["mealTimes"] as? [String]{
self.mealTimes = mealTimes
}
Now I would like to filter fetch results by strings in mealTime property. I have tried this way:
let predicate = NSPredicate(format: "mealTimes LIKE[cd] '*%#*'", "breakfast")
var breakfastContents = StaticContent.fetchStaticContentsWithPredicate(predicate, inManagedObjectContext: self.coreDataStack.context)
if (breakfastContents.count > 0) {
breakfast = breakfastContents.first!
}
The problem is that result array is empty but I know I have breakfast string in some content. So how can I fix it? I was reading something about saving transformable as NSData so it would need some great trick. I was trying to use LIKE (with and without *) command and CONTAINS.
Extension for StaticContent:
class func fetchStaticContentsWithPredicate(predicate: NSPredicate, inManagedObjectContext managedObjectContext: NSManagedObjectContext) -> [StaticContent] {
// Define fetch request/predicate
var fetchRequest = NSFetchRequest(entityName: "StaticContent")
// Assign fetch request properties
fetchRequest.predicate = predicate
fetchRequest.sortDescriptors = [NSSortDescriptor(key: "id", ascending: true)]
// Handle results
let fetchedResults = managedObjectContext.executeFetchRequest(fetchRequest, error: nil) as! [StaticContent]
return fetchedResults
}
You should refactor your data model to get rid of the "array of strings". This is not a very sound way to store this type of values.
Instead, consider a relationship with a new entity that captures those strings. Alternatively, device a scheme where you store a string and have a unique character that separates the records (e.g ; or something similar). Then any simple string predicate would work, like this:
NSPredicate(format: "mealtimes contains[cd] %#", "breakfast")

Resources