MusicCatalogResourceRequest<MusicKit.Artist> Result Missing Instance Properties

Hello!

I am trying a basic MusicCatalogResourceRequest to pull in a particular Artist from Apple Music. When printing out the result, it only contains the id and name of the Artist;

ex : Artist(id: "78011850", name: "deadmau5")

It is missing all of the instance properties as defined on the developer documentation.

This is the snippet I am using, is there something missing? I am trying to fetch the related albums, but it is always returning nil.

static func catalogAlbumsForArtistId(artistId: MusicItemID) async -> MusicItemCollection<MusicKit.Album>? {
    do {
        let artistRequest = MusicCatalogResourceRequest<MusicKit.Artist>(matching: \.id, equalTo: artistId)
        let artistResponse = try await artistRequest.response()

        if let artist = artistResponse.items.first {
            print("artist")
            return artist.albums
        }
    } catch {
        print(error)
    }
    return nil
}

Thanks! 😃

Accepted Reply

Hello @cheddarburrito,

First, let me point out that Artist conforms to the CustomStringConvertible protocol, which allows us to provide a custom description for an artist; this is what you see when you print an artist to your console. Music items in MusicKit are designed to have a very terse description, so that printing large collections of items can produce output that is meaningful and understandable at a glance, only highlighting the most important important attributes.

Some music item types in MusicKit, such as Album offer a more verbose debugDescription, such that you could get a more complete (although not necessarily exhaustive) representation of the album by doing something like:

print("\(album.debugDescription")

So the important takeaway here is that you shouldn't rely on what you see when you print a music item to know which properties are set on it.

That said, I understand you're trying to access the albums relationship on an Artist. To do that, you need to make sure to follow the two step process for loading and accessing relationships, outlined in the first part of the Meet MusicKit for Swift session.

So in your code, you need to replace these few lines:

        if let artist = artistResponse.items.first {
            print("artist")
            return artist.albums
        }

with:

        if let artist = artistResponse.items.first {
            let detailedArtist = try await artist.with([.albums])
            return detailedArtist.albums
        }

Also, keep in mind you can load more than one relationship (or association) at a time, by including in the array passed to the with() method a full list of all the properties you're interested in; you don't even have to refer to the documentation to see what's available, as autocompletion will help you figure out exactly what you can include in this array.

I hope this helps.

Best regards,

Replies

Hello @cheddarburrito,

First, let me point out that Artist conforms to the CustomStringConvertible protocol, which allows us to provide a custom description for an artist; this is what you see when you print an artist to your console. Music items in MusicKit are designed to have a very terse description, so that printing large collections of items can produce output that is meaningful and understandable at a glance, only highlighting the most important important attributes.

Some music item types in MusicKit, such as Album offer a more verbose debugDescription, such that you could get a more complete (although not necessarily exhaustive) representation of the album by doing something like:

print("\(album.debugDescription")

So the important takeaway here is that you shouldn't rely on what you see when you print a music item to know which properties are set on it.

That said, I understand you're trying to access the albums relationship on an Artist. To do that, you need to make sure to follow the two step process for loading and accessing relationships, outlined in the first part of the Meet MusicKit for Swift session.

So in your code, you need to replace these few lines:

        if let artist = artistResponse.items.first {
            print("artist")
            return artist.albums
        }

with:

        if let artist = artistResponse.items.first {
            let detailedArtist = try await artist.with([.albums])
            return detailedArtist.albums
        }

Also, keep in mind you can load more than one relationship (or association) at a time, by including in the array passed to the with() method a full list of all the properties you're interested in; you don't even have to refer to the documentation to see what's available, as autocompletion will help you figure out exactly what you can include in this array.

I hope this helps.

Best regards,

Thanks! That clears it up :)