-1

Context

I am building an app that uses CoreData. When opening a NewEntityForm, the app creates an Object of this Entity for the User to manipulate. When the User saves his changes, it gets saved to Context, otherwise it gets discarded using object.rollback().

This means that at any time there can be Uncommitted Objects in the given Context. However, I only want to present the saved ones inside the App expect from the NewEntityForm.


Code

This Code fetches all Objects, saved to context and temporary.

FetchRequest(sortDescriptors: [SortDescriptor(\.name, order: .forward)])

Question

  • How can I adjust my FetchRequest so that it only returns Objects already saved to the Context and ignores Uncommitted Objects.
christophriepe
  • 1,157
  • 12
  • 47
  • 1
    What about using 2 context, one for "temp", and one for "present in store"? – Larme May 15 '23 at 15:09
  • 1
    Please watch this video: https://www.youtube.com/watch?v=P8rqjs_CNsk . It describes how to use two separate contexts for creating and editing Core Data records.. – vadian May 15 '23 at 15:45
  • 1
    child context is the way to go, it is demonstrated in Apple's CoreDataBooks sample https://developer.apple.com/library/archive/samplecode/CoreDataBooks/Introduction/Intro.html#//apple_ref/doc/uid/DTS40008405 – malhal May 15 '23 at 19:18
  • @vadian great video. Thanks for the recommendation – christophriepe May 16 '23 at 07:31
  • @Larme, vadian, malhal thanks a lot for your support. I implemented this but encountered another problem: https://stackoverflow.com/questions/76260799/how-to-assign-object-from-maincontext-to-object-in-childcontext-using-a-picker-i. Any idea on how to solve this? – christophriepe May 16 '23 at 08:22

1 Answers1

1

How can I adjust my FetchRequest so that it only returns Objects already saved to the Context and ignores Uncommitted Objects.

A managed object context is often described as a "scratch pad" for objects -- it's very purpose it to keep track of new objects and changes to existing ones before they're saved. Once you save the objects in a context, everything is written back to the context's parent store. Therefore, if you want to ignore unsaved changes, you should create a new managed object context with the same parent store. Or, if the parent store is another managed object context, you can just make the fetch request in that context.

Caleb
  • 124,013
  • 19
  • 183
  • 272
  • Thanks a lot for your answer. Guided by your answer I was thinking of the following type of architecture: I have a standard context used for displaying data within my app and a temporary context for my forms which is copied over from the standard context. My Question would be whether that is a sufficient architecture and how I can merge the temporary context back to the standard context once the user saves his changes, especially while keeping iCloud Sync in mind which could change the standard context while the user is editing the temporary one. Thanks a lot for your support! – christophriepe May 15 '23 at 15:26
  • If the "standard" context is the parent of the temporary one that holds the unsaved changes, then the changes will automatically be merged into the standard context when you save the temporary one. – Caleb May 15 '23 at 15:37
  • sounds great. And this does not conflict with iCloud Sync? – christophriepe May 15 '23 at 15:40
  • Remember that the "standard" context is also a managed object context, so you'll eventually need to save *that* as well. If you're using Core Data with CloudKit then the persistent store will probably be a NSPersistentCloudKitContainer, and when you save the context that uses that store the changes will then be written to iCloud. – Caleb May 15 '23 at 15:48
  • Perfect. I've implemented your suggestion and it works just fine. However, I came across one problem. When creating a new `Item()` in a `ChildContext` which has a relationship to `AnotherItem()`, which is only in the `MainContext`, I cannot assign the `AnotherItem()` to the `Item()` using a `Picker()` for example. That causes the app to crash. Any idea on how to solve this issue? – christophriepe May 16 '23 at 08:13
  • That sounds like a separate problem that'd be worth creating a new question for instead of trying to solve in the comments. I don't think you're supposed to associate two objects unless they both exist in the same context, though. – Caleb May 16 '23 at 15:51
  • I've created a new question for this: https://stackoverflow.com/questions/76260799/how-to-assign-object-from-maincontext-to-object-in-childcontext-using-a-picker-i?noredirect=1#comment134482757_76260799. – christophriepe May 16 '23 at 16:51