MusicKit Custom Data Request

Hi,

I am trying to use MusicDataRequest from MusicKit to get the user's library artists (https://api.music.apple.com/v1/me/library/artists). This works well, until I am trying to use pagination with it. The data returned by this endpoint contains a "next" property, which reads /v1/me/library/artists?offset=25. Replacing the URL as such resulting in https://api.music.apple.com/v1/me/library/artists?offset=25 no longer works, as the request returns an error:

MusicDataRequest.Error(
   status: 400,
   code: 40008,
   title: "Invalid Path Value",
   detailText: "Unknown library resource type 'artists?offset=25'",
   ...
)

It seems like the request cannot handle query parameters and considers them as part of the request's path.

Is there any way to use query parameters with MusicDataRequest?

Thanks for any response.

Actually it seems the "next" property contains an invalid path, it returns "artists?offset=25" and should return "artists/?offset=25"

Hello @sharedRoutine,

The value of the "next" property is actually just fine. You just need to be very careful when manipulating URLs. That's why in general, you're always better off using URLComponents when manipulating URLs.

But more importantly, you can do this much more simply using MusicKit, so you won't even need to use the "next" field directly. Indeed, since the response from the Get All Library Artists endpoint is a resource collection of artists, you can just decode it using MusicItemCollection.

Once you have your collection of artists, you can just check for the presence of a next batch using MusicItemCollection's hasNextBatch property, and then load it using the nextBatch(limit:) function:

let url = URL(string: "https://api.music.apple.com/v1/me/library/artists")!
let dataRequest = MusicDataRequest(urlRequest: URLRequest(url: url))
let dataResponse = try await dataRequest.response()

let decoder = JSONDecoder()
let artists = try decoder.decode(MusicItemCollection<Artist>.self, from: dataResponse.data)

print("artists = \(artists)")

if artists.hasNextBatch {
    if let nextArtists = try await artists.nextBatch() {
        print("nextArtists = \(nextArtists)")
    }
}

Here's the abbreviated output I see for this code:

artists = MusicItemCollection<Artist>(
  items: [
    Artist(id: "r.JQh8U77", name: "Ana Tijoux"),
    [...]
  ],
  hasNextBatch: true
)

nextArtists = MusicItemCollection<Artist>(
  items: [
    Artist(id: "r.58OQvyt", name: "Berry"),
    [...]
  ],
  hasNextBatch: true
)

I hope this helps.

Best regards,

Hello @sharedRoutine,

I just wanted to let you know you no longer need to use MusicDataRequest on iOS 16 beta 1 to fetch artists from the user's library.

Instead, you can use the brand new MusicLibraryRequest in MusicKit.

Please check our new WWDC22 session video, Explore more content with MusicKit, which goes into this, and much more!

I hope you'll like it!

Best regards,

MusicKit Custom Data Request
 
 
Q