Mastering In CoreData (Part 16 Multithreading Concurrency Strategy Parent — Child Use Case 2)
Discard Temporary Changes Using Parent Child Strategy
In this Part we will see how we can used Parent — Child Managed Object Context strategy for temporary UI changes to Core data objects. First download the starter project .
Note: See part 14 and 15 about Parent — Child Managed Object Context strategy.
When application first launched you will redirect to User screen as shown in the Figure 1. Tap on details button will perform two tasks. First it will increment the login attempt(Entity) counter then it it will redirect you to User detail screen where it will show user complete information where user can edit information in that screen as shown in Figure 2
Figure 2 is the User Detail screen where user can edit their information. On back it moves to the previous screen (User screen) and discard temporary changes. Tap on save button will update changes to the Core Data
The project structure to describe the temporary change problem is shown in Figure 3
AppDelegate → Responsible for creating Core Data stack.
ViewController → Contains logic to show user and user can tap on details button to redirect to user detail screen. (User Screen)
UserDetailViewController → Contains logic to show User detail information from Core Data and logic to save changes to database when user tap on save button after editing their information
TemporaryChanges.xcdatamodeld → Contains two entity
- User → contains properties
- LoginAttempt → contains property count
When you first launch an application, User with
lastname will save into the persistent store if not exists and its f
firstname will display on the label as shown in Figure 4
Now when you tap on detail button it will perform two tasks
- It will increment
countproperty to +1 and save it to the persistent store by calling
- Redirect to detail screen using storyboard segue
Now tap on Detail button on User screen and it will redirect you to user detail screen as shown in Figure 6. In this screen user details are showing. User can update their information and save it to the database by hitting save button or discard their temporary changes by tap on back button.
Change user detail information as shown in Figure 7 we changed
Ali temp and also updated
lastname as well
When user end typing on any text field it will update User core data object of type
NSMangedObject which is instance property of the controller. Now when user finished
firstname textfield this update will reflect to
user object as well which is sitting in the context
As we know that User object was populated on main thread context and when we performed temporary changes it will update the object in the context and when we tap on back button updated value still present in the context. Now after tapping on back button User screen will appear. We know that when we tap on detail button it will first increment the counter and call
save method by calling save method it will push users temporary changes to persistent store as well and redirect to User Detail screen with the updated value .
Due to Managed Object Context is a singleton object
save method will pushed the temporary changes to the persistent store
As you can see in the updated screen show User temporary changes appear. The problem is that we need to discard changes when user perform back button. There are three ways in which we can do this
- Using parent — child strategy (Cover in this part)
- Undo manger (Next part)
- Manually track changes (Will not cover)
Understand Problem Using Flow Diagram
As you can see in Figure 11 when application first launch User information will store into the persistent store . When you tap on detail button it will display user detailed information from the main context which is direct interacting with the UI
Now User Edit information and update their information on the direct coredata entity that was using to populating User Detail screen. At that point since User Detail populating their view using core data user object which is in main context. This change will reflect to context as well. Let’s suppose user want to discard this change by tap on back button, we have to have some mechanism to discard this change and the current application don’t support that. Since main context is singleton to whole application there may be a chance that save on the main context method will call anywhere from the app and this will merge changes to persistent store as well as shown in Figure 12.
When tap on back button and again come to this screen. Let’s suppose save method was not called so changes will not reflecting to persistent store. But
UserDetailViewController is Populating user detail from database. It will ask the singleton main thread context to give me the user data. Context first look into their cache if it found it will send the temporary updated user object. This is the problem so how can we discard the temporary changes with simple way
Understand Solution Using Flow Diagram ( parent child configuration)
As you can see in the Figure 14 . We are populating User Detail Screen using child context which is also created on main thread. As our rule we need to create UI related task context on main thread. We created both parent and child on main thread.
We created both parent and child on main thread.
As you can see in the Figure 14 since we are populating User detail screen from the object that was in child context so changes in the User screen will only reflect to the child context.
One thing you remembered while working with multiple managed object context is that each context contains has its own copy of nsmanagedObject.
When user tap back button we simply discard our child context and user is now User screen. As I said in previous tutorials as well Don’t make child context as a singleton whenever you need it simply create it and when you are done destroy it. As shown in Figure 15 User tap on back button we completely discard child context since it contains all temporary information when it destroy it will destroy all the temporary changes as well and you can see out parent and persistent store contains the original data
As you can see in Figure 16 . When you again come to User Detail Screen. UserDetailViewController will again create a child context and child context when created always have the same state as the parent, so user previous changes will not appear.
Let’s make a case when user tap on save instead of back. As you can see in the Figure 17. When user tapped on save button child need to merged those changes to parent and after that parent will pushed changes to persistent store. So two
save method will need to execute.
So, let’s first delete the application and as you can see in Figure 18 we did lots of things
- Created a child context on main thread since we are dealing with the UI related task
- Created parent child strategy where both parent and child is in main context. Parent context is singleton to the application whereas child context acts as an instance property of the controller. So after controller deallocate it will discard this context as well
- Fetched object from child Managed Object Context and also we populated Core Data User object (instance property of controller as well) with the child context
- Finally, when user tap on back button controller, this controller will pop and child context will discard with all the temporary changes
Now run application and again do the same flow as we shown above. You will see the problem will solve and now we actually discarding out temporary changes on the user object.
Finally when user tap on save button we are actually first pushed changes tn parent context using
save method on child context then we pushed changes to persistent store by calling
save method on parent context as well.
A managed object context is an in-memory scratchpad for working with your managed objects.We used multiple managed object context for performing two type of tasks. One task we talked in previous part . In this part we used parent — child context to discard temporary changes in the context.
In the next part we will look how we used UndoManager to solve temporary changes problem happened in the context