Set a SwiftUI Published Property To A Codable Structure From JSON Data

Daily Coding Tip 018

This is based on a post on my Substack, but I’ve expanded it into a working example.

I haven’t worked with Combine much, but I wanted an easy way to get data into my SwiftUI project without using the conventional URLRequest.dataTask.

Instead of creating a Publisher in my ObservableObject, I decided to create an extension of URL that would assign a dataTaskPublisher to one of my existing @Published properties.

The function has a generic parameter, but the parameter has to conform to the Codable protocol. This means that it can be created from the data that the dataTaskPublisher returns, provided that the data matches the expected structure.

Because this is an extension of Apple’s provided URL class, we already have access to a URL in the form of the current instance self. We need the code to run on the main queue, as otherwise the @Published property would not update the SwiftUI views displaying the data.

.map(\.data) is used to reduce the results to the data alone as otherwise we would also have access to the server response to the request. Now we can actually decode the data into the Codable structure, as we know that the type we’ll be returning conforms to that protocol.

I used assertNoFailure in order to ensure that there are no errors at this stage. Without doing this, I would not be able to assign the resulting structure back to the @Published property that was passed to the function.

The data we’ll be retrieving is from the API for the webcomic XKCD.

Most of these properties won’t be used in our example, but it’s useful to have the data in case you want to try displaying the other information.

My DataModel class has a @Published property that stores the XKCD data, but it is nil by default. In the initialiser for the DataModel class, I call my getFromPublisher function on a URL. This will give us the data, but we also need to set the image. The image will be set by the getImage function, which will be called in the SwiftUI.

The last thing we need to do is display the data, which is what SwiftUI is for!

As you can see, the SwiftUI is not displayed until the XKCD data has been loaded. When it is loaded, the title is displayed at the top. When the title appears it calls dataModel.getImage() and, when the image is set it is displayed underneath.

This particular endpoint only shows the latest comic, but feel free to add more functionality if you want.

Get more Daily Coding Tips in your inbox!