Core Data: Beyond the Basics

Jul 26 2022 · Swift 5.5, iOS 15, Xcode 13.3.1

Part 1: Fetching & Displaying Launches

11. Transient Properties

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: 10. Challenge - Displaying Tags Next episode: 12. 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.

Transcript: 11. Transient Properties

Good job on those challenges! You’ve implemented quite a few challenging features so let’s end this part of the course on an easier note. There’s one little thing I’d like to add to the app, and that is to display how many RocketLaunches are associated with each tag.

You could do this by executing a fetch request and counting the results but if you want to do this in several places you need to define fetch requests all over the place which isn’t the best approach - the more you duplicate your logic the more you leave room for error.

Instead you’re going to use Core Data’s transient properties. Navigate to the RocketLaunch data model, select the Tag entity and add a new attribute named launchCount. Set the type to Integer16 and in the data model inspector check the transient box. You’re also going to uncheck the optional box and give it a default value of 0.

You can think of transient properties like computed properties, except they are managed by core data. A transient property is one that is defined in the model, but not saved in the persistent store. Core Data still keeps track of changes to the property in a managed object context but doesn’t save these changes. Transient properties, like computed properties, are useful for computing information based on other properties on the model.

Let’s define one. Start by declaring a property with the @objc keyword.

@objc var launchCount: Int {}

You’re doing this because while this is like a computed property, you want to expose it to the Objective-C runtime so it can be managed by Core Data.

Inside the property declaration you’re going to call a method on NSManagedObject, willAccessValue(forKey:)

willAccessValue(forKey: "launches")

This method takes a key path to an attribute on the same entity and informs Core Data, through key value observing, that the launches property is about to be accessed.

Next you’ll go ahead and access that property and use it to determine a count value

let count = launches.count

After accessing it you’ll tell Core Data that you’re done using it with the didAccessValue(forKey:) method.

didAccessValue(forKey: "launches")

Like its counterpart this tells Core Data that you went ahead and accessed it. Now you can return the value

return count

Let’s use this property in the TagsView to display the number of launches for each tag. Change the Text view inside the ForEach to the following:

Text("\(tag.title) (\(tag.launchCount))")

Build and run the app. If you navigate to the tags view you should see the count for each tag.

So what was the point of this? You could’ve achieved the same functionality with a computed property without the extra method calls. Actually, it’s the extra method calls that make this really useful but to understand that you need to take a slight peek behind the curtains at how Core Data handles things.

One concept I haven’t touched on yet is faulting. When you load the app the first screen you see is a series of launch lists. All of those lists have launches associated with them but they aren’t all fetched immediately when the lists are fetched. If they were that would be extremely inefficient because the app would be holding more data than is necessary in memory.

Have the simulator running to show this

Instead faulting solves this problem by using placeholder objects known as faults. When you’re on the first screen, all of those list objects have a launches property, but at that moment there are no launches fetched and held in memory. Instead Core Data uses a bunch of placeholders. This limits the size of the object graph and saves memory. When you access the launches property on the list object, the fault is realized and Core Data automatically fetches the data associated with that relationship.

So why does this matter, especially in the context of transient properties? Two reasons - by informing Core Data that you are about to access a property Core Data can realize any faults and fetch the data for you.

The second reason is because unlike a computed property, the managed object context actively keeps track of changes to transient properties. This means that even though the data is not stored you get all the benefits of Core Data like undo and redo, validation and so on. Many of these topics are concepts you won’t be covering in this course, but when you do you’ll be able to use them with transient properties as well.

In the next video let’s wrap up this part of the course and recap what you’ve learned.