Question about temporarily storing objects #57

Closed
opened 2025-12-29 15:23:16 +01:00 by adam · 3 comments
Owner

Originally created by @jyounus on GitHub (May 8, 2016).

Hey there,

This is probably a more CoreData related question rather than a CoreStore specific one, but I'm hoping you can guide me in the right direction.

I'm currently not using CoreData or any other database in my project, I download relevant data in memory as required and utilise httpcache with etags to save bandwidth and not redownload a JSON that I already have available in my local disk cache.

I now want to improve the app by adding a local database (and at the same time improve the user experience for a very specific section of the app that will definitely benefit by using a local database).

I've been thinking about what the best way would be for me to move over to CoreData and there's one scenario that I'm not really sure about.

I have the following problem:
A user can create an account and set up their profile. Now let's say the user decides to edit some details, what I currently do is work out the difference and then post that change back to my API.

This is easy enough for me to do with a "normal" object (what I mean with normal is something like a custom "UserJSON" class that takes in a dictionary and gives me a formatted Swift object. "Normal" as in it's not an NSManagedObject subclass or part of any database, it literally is just an in-memory object).

What I do right now:

  1. Fetch the current user's data in memory (let's refer to this as U1).
  2. User decides to change his/her profile, I create a copy of the object I have from step 1 and pass that into the subsequent ViewControllers to update as required (let's call the copy U2).
  3. Once the user saves, I compare U2 against U1 and create a new User object which only has properties initialised which are different, this would be U3.
  4. I make an API call to update the current user's details by sending it the U3 object.

My question is, how can I use the above approach and do this with CoreData/CoreStore? I want to copy/duplicate an object but only temporarily. I need to be able to pass this duplicated object into a number of different ViewControllers which handle the different options a user can modify.

I can think of using 2 separate DataStacks with CoreStore, the first one is my main DataStack and the other is just for any temporary objects that I would clear on each app start or so. But can I pass/"edit" between two different DataStacks? I know there's an edit function, but the readme says that's for objects for the same DataStacks (just a different transaction), it doesn't really mention anything about sharing something across DataStacks. Is this possible?

An alternative I can think of is having an extra bool flag called something like "isTemp" and use that with just 1 DataStack.

And the final alternative I can think of is not saving the object at all and use it as an "unsafe" transaction and pass that between my ViewControllers. My issue with this is if the user quits the app, I will lose the current changes and that's not really idea. I want to temporarily save after each change the user makes and be able to carry on when the user runs the app again.

What would you recommend I do? Thanks in advance and sorry for such a long essay!

Originally created by @jyounus on GitHub (May 8, 2016). Hey there, This is probably a more CoreData related question rather than a CoreStore specific one, but I'm hoping you can guide me in the right direction. I'm currently not using CoreData or any other database in my project, I download relevant data in memory as required and utilise httpcache with etags to save bandwidth and not redownload a JSON that I already have available in my local disk cache. I now want to improve the app by adding a local database (and at the same time improve the user experience for a very specific section of the app that will definitely benefit by using a local database). I've been thinking about what the best way would be for me to move over to CoreData and there's one scenario that I'm not really sure about. I have the following problem: A user can create an account and set up their profile. Now let's say the user decides to edit some details, what I currently do is work out the difference and then post that change back to my API. This is easy enough for me to do with a "normal" object (what I mean with normal is something like a custom "UserJSON" class that takes in a dictionary and gives me a formatted Swift object. "Normal" as in it's not an NSManagedObject subclass or part of any database, it literally is just an in-memory object). What I do right now: 1. Fetch the current user's data in memory (let's refer to this as U1). 2. User decides to change his/her profile, I create a copy of the object I have from step 1 and pass that into the subsequent ViewControllers to update as required (let's call the copy U2). 3. Once the user saves, I compare U2 against U1 and create a new User object which only has properties initialised which are different, this would be U3. 4. I make an API call to update the current user's details by sending it the U3 object. My question is, how can I use the above approach and do this with CoreData/CoreStore? I want to copy/duplicate an object but only temporarily. I need to be able to pass this duplicated object into a number of different ViewControllers which handle the different options a user can modify. I can think of using 2 separate DataStacks with CoreStore, the first one is my main DataStack and the other is just for any temporary objects that I would clear on each app start or so. But can I pass/"edit" between two different DataStacks? I know there's an edit function, but the readme says that's for objects for the same DataStacks (just a different transaction), it doesn't really mention anything about sharing something across DataStacks. Is this possible? An alternative I can think of is having an extra bool flag called something like "isTemp" and use that with just 1 DataStack. And the final alternative I can think of is not saving the object at all and use it as an "unsafe" transaction and pass that between my ViewControllers. My issue with this is if the user quits the app, I will lose the current changes and that's not really idea. I want to temporarily save after each change the user makes and be able to carry on when the user runs the app again. What would you recommend I do? Thanks in advance and sorry for such a long essay!
adam added the question label 2025-12-29 15:23:16 +01:00
adam closed this issue 2025-12-29 15:23:16 +01:00
Author
Owner

@JohnEstropia commented on GitHub (May 8, 2016):

I don't recommend separating the DataStack because then you can't communicate the original object and the temporary object. Separating stacks is meant for managing completely unrelated objects.

How about separating the entity class for the original and the temporary object? I can think of 3 hierarchies this can work:

  1. A BaseUserData abstract class, a PendingUserData that is a subclass of the base, and a UserData that is a subclass of PendingUserData.
  2. A BaseUserData abstract class, a UserData that is a subclass of the base, and a PendingUserData that is a subclass of UserData.
  3. A BaseUserData abstract class, a UserData that is a subclass of the base, and a PendingUserData that is also a subclass of the base.

With (1) and (2) though, you need to be careful when fetching because you might accidentally fetch the subclass instance when fetching the base class instance:

// example for (1)
class BaseUserData: NSManagedObject { ... }
class PendingUserData: BaseUserData { ... }
class UserData: PendingUserData { ... }

// when fetching a UserData:
let actual = CoreStore.fetchOne(From(UserData)) // OK. UserData is the leaf subclass so you wont accidentally get a PendingUserData instance

// when fetching a PendingUserData:
// let pending = CoreStore.fetchOne(From(PendingUserData)) // WRONG! You might get a UserData instance
let pending = CoreStore.fetchOne(
    From(PendingUserData),
    Tweak { $0.includesSubentities = false } // Correct! You need to do this
)

For the reasons above, I recommend (3) which makes UserData and PendingUserData sibling objects so as long as you fetch with From(UserData) and From(PendingUserData) you are guaranteed to get the correct entity.

@JohnEstropia commented on GitHub (May 8, 2016): I don't recommend separating the DataStack because then you can't communicate the original object and the temporary object. Separating stacks is meant for managing completely unrelated objects. How about separating the entity class for the original and the temporary object? I can think of 3 hierarchies this can work: 1. A `BaseUserData` abstract class, a `PendingUserData` that is a subclass of the base, and a `UserData` that is a subclass of `PendingUserData`. 2. A `BaseUserData` abstract class, a `UserData` that is a subclass of the base, and a `PendingUserData` that is a subclass of `UserData`. 3. A `BaseUserData` abstract class, a `UserData` that is a subclass of the base, and a `PendingUserData` that is also a subclass of the base. With (1) and (2) though, you need to be careful when fetching because you might accidentally fetch the subclass instance when fetching the base class instance: ``` swift // example for (1) class BaseUserData: NSManagedObject { ... } class PendingUserData: BaseUserData { ... } class UserData: PendingUserData { ... } // when fetching a UserData: let actual = CoreStore.fetchOne(From(UserData)) // OK. UserData is the leaf subclass so you wont accidentally get a PendingUserData instance // when fetching a PendingUserData: // let pending = CoreStore.fetchOne(From(PendingUserData)) // WRONG! You might get a UserData instance let pending = CoreStore.fetchOne( From(PendingUserData), Tweak { $0.includesSubentities = false } // Correct! You need to do this ) ``` For the reasons above, I recommend (3) which makes `UserData` and `PendingUserData` sibling objects so as long as you fetch with `From(UserData)` and `From(PendingUserData)` you are guaranteed to get the correct entity.
Author
Owner

@jyounus commented on GitHub (May 8, 2016):

That seems like a good idea, why didn't I think of that!?

Will give this a go once I start with the offline support stuff on my app. Thank you very much for your help! :D

@jyounus commented on GitHub (May 8, 2016): That seems like a good idea, why didn't I think of that!? Will give this a go once I start with the offline support stuff on my app. Thank you very much for your help! :D
Author
Owner

@JohnEstropia commented on GitHub (May 8, 2016):

Glad to be of help :) Good luck!

@JohnEstropia commented on GitHub (May 8, 2016): Glad to be of help :) Good luck!
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/CoreStore#57