Core Data: Fundamentals

Jul 19 2022 · Swift 5.5, iOS 15.4, Xcode 13.3.1

Part 2: Saving Launches

12. Inserting Data Into the Context

Episode complete

Play next episode

Next
About this episode

Leave a rating/review

See forum comments
Cinema mode Mark complete Download course materials
Previous episode: 11. Creating Managed Objects Next episode: 13. Conclusion

Get immediate access to this and 4,000+ other videos and books.

Take your career further with a Kodeco Personal Plan. With unlimited access to over 40+ books and 4,000+ professional videos in a single subscription, it's simply the best investment you can make in your development career.

Learn more Already a subscriber? Sign in.

Heads up... You've reached locked video content where the transcript will be shown as obfuscated text.

In the last video, you created a ManagedObject subclass for the rocket launch entity. Now you can use this class to create instances of a rocket launch for users to save. If you build and run the app, you'll see a new rocket launch button at the bottom of the screen. When you tap on that, you're presented with a modal view to enter details about the rocket launch. Back in the code base, this modal view is represented by the LaunchCreateView type and this is where you'll add code to save a rocket launch. Near the bottom of that view, you should see a button with the text Save. All this button is doing right now is dismissing the modal view when tapped. Above the dismiss call on the presentation mode, let's create an instance of RocketLaunch. When you type out the open parentheses to create an instance, you'll see that there are a couple initializers you can use. The first one takes a ManagedObject context and the second one an entity description and a context. As mentioned earlier, all ManagedObjects need to be inserted into the context so that it can keep track of all the changes. That's what's happening here when you pass in the context. The designated initializer handles registering the instance you create with the context. But where do you obtain the context from? Earlier, you created a CoreData stack using the NSPersistentContainer class. Let's use that to obtain a ManagedObject context. As we discussed earlier, the context is the only part of the stack you're going to be exposing to the rest of our app. Navigate to RocketLaunchesApp, and here you can see that an instance of ContentView has been created and assigned as the main view of the WindowGroup, which is what is presented when the app starts. If you'd worked with SwiftUI before, you should be familiar with the environment object, which is a property wrapper for an observable object that lets us share data around the app. For any given view, an environment object must be supplied by its parent. So if we take that logic all the way back to the ancestor view of all the views in the app, the ContentView, in this case, must supply the environment object. Recall that when you made the persistenceController, there were two static properties to fetch a controller from anywhere in your app. Add the following to the top of the RocketLaunchesApp struct. Now that you have access to the persistenceController, we can place its context into the environment using the environment modifier and the managedObjectContext key path. Great. You now have a context that you can use elsewhere in the app. Navigate back to the LaunchCreateView and import CoreData. You can now access the managedObjectContext by using the @Environment property wrapper, along with the key path to access the value on the environment object. Now that you have the context, you can use it to create an instance of RocketLaunch. You can now set values on this instance and because the storage of these properties are managed by CoreData, the context will keep track of it for you. This feels very much like assigning values to any other instance you work with in Swift and that's intentional. If this were overly cumbersome, most people wouldn't use CoreData but there is no real backing instance. Remember, we just inserted a new RocketLaunch entity into the context and it's now keeping track of the values it eventually needs to hand off to the persistence store. These values are not persisted until you call Save on the context, so let's go ahead and do that. The managedObjectContext defines a save method that you can call but it's a throwing one, so you'll need to use a do catch clause. If this fails, you'll just log the error and crash the app. If this were a real app, you would need to provide proper error handling to let the user know something went wrong. Now when you tap on the Save button, the RocketLaunch will actually be saved to the persistent store. Pretty cool, huh? Before we test this out, let's clean up the code a bit. What you just wrote here, creating a RocketLaunch and assigning values to the instance, that's a common bit of code that you can refactor into a method and automatically save. Select all the code you just added and hit Command + C to copy. Navigate to RocketLaunch+CoreDataProperties and add a static method. Now paste the copied code in here using Command + V. You'll need to make a couple of minor changes and remove all the self-calls and change from viewContext to managedObjectContext. Now back in LaunchCreateView, you can replace the entity code with your new method. Let's test this out. Build and run the app. Tap on the new rocket launch button at the bottom to create a new rocket launch. Give it a title, a launchpad, and some notes. Tap on Save and if it doesn't crash, that means you're good to go. When the modal is dismissed and you land back on the list view, you still see the test data. In part two of this course, you'll fix this by fetching rocket launches from the persistent store. Before heading there, let's recap what you've learned in this course, which is the next video.