-1

After fetching Core Data objects, I need to re-fetch the same set of objects later. I know all IDs, but objects could be changed, so need to fetch again by objectID, all at once. How to achieve that?

PS: I cannot just use same predicate as first fetching because new objects could be added, I don't need them.

bodich
  • 1,708
  • 12
  • 31
  • 1
    I don't know why people are voting to close. The question is clear and specific. – Tom Harrington Jul 28 '20 at 17:10
  • You can get an object by objectID from the managed object context without `fetch`ing the objects. `Map`ping the objectIDs to the objects might be more efficient than applying a predicate. – vadian Jul 28 '20 at 17:16
  • Vadian, not sure I understood your solution of mapping without fetch. – bodich Jul 28 '20 at 20:47

1 Answers1

4

If you have an array of object IDs, you can fetch all of the objects for those IDs at once with the right predicate. It would be something like

let objectIDs: [NSManagedObjectID] = // Your object IDs from a previous fetch
let predicate = NSPredicate(format: "self in %@", objectIDs)

Then use that predicate in a fetch.

That predicate says to get every object with an object ID in the array. Newer objects of the same type won't be included.

Additional: The "map" approach mentioned by @vadian would be something like this, where MyClass is the name of your managed object class:

let results: [MyClass] = objectIDs.compactMap { try? context.existingObject(with: $0) as? MyClass }

With this code, you need to use existingObject(with:) instead of object(with:) because you mentioned that you might have deleted some of the objects. Using object(with:) in that case could get you some bogus results, because that function always returns a managed object even if there isn't one with the object ID.

If you only have a few object IDs, performance is probably very similar for each of these approaches. With larger collections I suspect that compactMap would be slower because it needs to ask the context for each object individually. The predicate approach asks for everything at once and lets SQLite handle the lookup. I'm not certain about the comparison though, so it's possible it's the other way around for some reason.

Tom Harrington
  • 69,312
  • 10
  • 146
  • 170
  • Thank you Tom. I’ll check it and accept your answer if works! You perfectly understood what I was need. One question. If any of those object removed, will it cause an fatal error or just skip removed objects? – bodich Jul 28 '20 at 20:43
  • 1
    It doesn't matter if you have removed some of the objects. You'll get whatever objects match the IDs in the array. If some IDs aren't valid anymore, they'll be ignored. – Tom Harrington Jul 28 '20 at 23:24
  • 1
    @bodich I added the "map" approach mentioned in a comment on the question. – Tom Harrington Jul 29 '20 at 22:00