Leave a rating/review
Notes: 14. Asynchronously Loading Launches
- The SpaceXAPI - https://github.com/r-spacex/SpaceX-API
- WWDC21 - Intro to async/await - https://www.raywenderlich.com/25008723-wwdc-2021-intro-to-async-await
Until now in the course, you’ve been dealing with small amounts of data that gets inputted by the user. Easy right? Well, Core Data can also handle large amount of data that you want to store all at once. In fact, this is one of the reasons you might want to use a persistence mechanism such as Core Data in your app - large amounts of data with a non-trivial relationship between entities.
To see how we can handle large volumes of data with Core Data (and keep the user interface responsive), we first need a much larger dataset than what we’re dealing with now. Luckily, there is an open source API for downloading information about SpaceX rocket launches!
The starter code for this project has a few new additions since last episode: model files for a few different types of data, and a SpaceXAPI file that contains helpful API you can use when fetching data from the network. In this episode, you’ll look at some of the unique features that allow you to grab that data and get it ready to store in Core Data. Note that this episode will NOT cover the details of getting this data from the network - there are other resources available here at the site that can help you with that. Instead, you’ll learn about a few things you’ll need to do in order to get the data ready to use later on.
There’s a lot of similarity between the various structs defined in the starter project, so let’s focus on updating SpaceXFairings (the other model classes in the starter project are ready to go).
You can find the SpaceX API in the author’s notes for this episode.
Show API in a browser
There you can see that the SpaceXFairings contains 4 fields: reused, recoveryAttempt, and recovered, which are all booleans, and ships, which is an array of Strings.
The struct for this is designed to match, with the addition of a UUID to make sure each element is unique.
Show the starter code in Xcode
Our struct though is slightly different - there aren’t underscores in our property names, but there are in the recovery_attempt field of the JSON. You can map between the incoming names and the property names by using CodingKeys
private enum CodingKeys: String, CodingKey {
case reused
case recoveryAttempt = "recovery_attempt"
case recovered
case ships
}
To see how this struct is used, let’s go to the SpaceXLaunchJSON file.
Show the SpaceXLaunchJSON file in Xcode
As you can see, a lot of things go into tracking a SpaceX launch! The fairings object is right at the top. When the launch JSON is read, one of the fields read in is the fairings. The JSONDecoder knows for custom types to reference those types to see how to decode them - that’s where the CodingKeys you defined come into play. But where is the launch decoded? Let’s go to the SpaceXAPI file
Show the SpaceXAPI file in Xcode
This file contains a series of static calls that can be used in the app to call various REST endpoints. For example, getAllLaunches does just what it says - it calls the URL that gets all launches in the database. The loadJSON method takes in the URL as well as a type - here, SpaceXLaunchJSON, that the objects will be decoded with.
At the bottom of the file, the loadJSON function is the workhorse here, and where we first encounter some async behavior in the app. The function is generic over types that adopt Codable - which the SpaceX model structs do, and use a common async/await pattern to contact the URL, get the data, and then uses the JSONDecoder to convert it to the passed in type T. If you aren’t familiar with async/await, or need a refresher, there is a link in the notes for this episode.
In the upcoming episodes you’ll use these API calls to grab data to make several different lists in the app. In the next episode, you’ll update the code to handle batch Core Data insertions, before moving on to take advantage of new Core Data API that use Swift Concurrency.