I'm trying to fetch the top playlists from Apple Music using the charts API and I have the following code:
func fetchPopularPlaylists() async throws -> [MusicItemCollection<Playlist>] {
var request = URLRequest(url: URL(string: "https://api.music.apple.com/v1/catalog/US/charts?types=playlists")!)
let userToken = try await fetchUserToken()
request.httpMethod = "GET"
request.addValue("Bearer \(Self.jwt)", forHTTPHeaderField: "Authorization")
request.addValue(userToken, forHTTPHeaderField: "Music-User-Token")
let dataRequest = MusicDataRequest(urlRequest: request)
let response = try await dataRequest.response()
let decoder = JSONDecoder()
let playlistResponse = try decoder.decode(MyChartsResponse.self, from: response.data)
return playlistResponse.results.playlists
}
And this code works well and as expected, I'm able to populate results. However, I believe that the response is getting decoded incorrectly.
My response model object:
struct MyChartsResponse: Codable {
struct Results: Codable {
let playlists: [MusicItemCollection<Playlist>]
}
let results: Results
}
The charts api however has the response listed in the form of:
{
"results": {
"playlists": [
// playlist entities here
]
}
}
This API response makes it seem like the proper Swift decoding structure is either
struct MyChartsResponse: Codable {
struct Results: Codable {
let playlists: MusicItemCollection<Playlist>
}
let results: Results
}
or
struct MyChartsResponse: Codable {
struct Results: Codable {
let playlists: [Playlist]
}
let results: Results
}
but instead the playlist property has to be Array<MusicItemCollection<Playlist>> in order to decode correctly with no custom decoding. The playlists property is incorrectly getting wrapped in an extraneous collection on decoding which makes extracting it difficult.
Selecting any option will automatically load the page