0

Update: I believe this is duplicate of this: Core Data - Fetch all entities using the same field

I want to use a UUID to find all managed objects that have a property with this ID, regardless of type.

In the typical case, I would use a fetch request on the entity itself. For example, in a Bookstore I could find a book by a bookUUID using a fetch request on Book.

class BookShelf: NSManagedObject {
    
    @NSManaged var bookUUID: UUID!

    func fetchBook() -> Book? {
        let request = Book.fetchRequest()
        request.sortDescriptors = []
        request.predicate = NSPredicate(format: "%K == %@", "bookUUID", bookUUID as CVarArg)
        return try? self.managedObjectContext?.fetch(request).first
    }
    
}

Here this works because BookShelf knows about Book. But what about the other way around? When a book deletes itself it should find any entities with a property bookUUID, regardless of their type.

It could be expressed this way, however this doesn't work. There is no generic NSManagedObject entity.

extension NSManagedObjectContext {
        
    func findAllObjectsUsingThisBook(bookUUID: UUID) -> Array<NSManagedObject>? {
        let request = NSFetchRequest<NSManagedObject>()
        request.predicate = NSPredicate(format: "%K == %Q", "bookUUID", uuid as CVarArg)
        request.sortDescriptors = []
        return try? self.fetch(request)
    }
    
}

Expressed generically, this could be used to find any objects with a certain property.

extension NSManagedObjectContext {
        
    func findAllObjectsWithProperty<T>(named propertyName: String, andValue value: T) -> Array<NSManagedObject>? where T: CVarArg {
        let request = NSFetchRequest<NSManagedObject>()
        request.predicate = NSPredicate(format: "%K == %Q", propertyName, value)
        request.sortDescriptors = []
        return try? self.fetch(request)
    }

}

How can I accomplish this?

MH175
  • 2,234
  • 1
  • 19
  • 35
  • 1
    You can’t, you need to search each entity separately. You can of course write a generic function and then call it in a loop for each entity – Joakim Danielson Dec 26 '21 at 09:17
  • You can use subclassing to do that, if I understood correctly your issue. But then, you might need to "cast afterwards" to have the correct subclass if needed. – Larme Dec 26 '21 at 09:40
  • Actually this is the purpose of a *Relationship*. The book is being created in **one** entity and can be connected to other entities with a relationship. If you delete the book it will be removed also in the related entities (depending on the settings). – vadian Dec 26 '21 at 09:44
  • @ Larme - Correct. In my particular use case I will just delete the objects without checking their type. – MH175 Dec 26 '21 at 09:46
  • @vadian - Indeed. I am trying to flatten a complex web of relationships. – MH175 Dec 26 '21 at 09:47

1 Answers1

0

I think you can create a parent entity like BookParent which has a property bookUUID, so you can use it like this NSFetchRequest<BookParent>(), you can find more details here.

When a book deletes itself it should find any entities with a property bookUUID, regardless of their type.

From your description, maybe you should create relationships and use cascade delete?

JIE WANG
  • 1,875
  • 1
  • 17
  • 27