Cannot decode library songs response for a non-Apple Music item

Hi there!

I am fetching library songs using the endpoint: https://api.music.apple.com/v1/me/library/songs

Here's the code snippet -

struct Songs: Decodable {
  let data: [Song]
}

public func librarySongs() async throws {
  let url = URL(string: "https://api.music.apple.com/v1/me/library/songs")

  guard let url = url else { return }

  let dataRequest = MusicDataRequest(urlRequest: URLRequest(url: url))

  do {
    let dataResponse = try await dataRequest.response()
    print(dataResponse.debugDescription)

    let response = try JSONDecoder().decode(Songs.self, from: dataResponse.data)
  } catch {
    print("**ERROR**")
    print(error)
    print(error.localizedDescription)
    }
}

Trying to decode it using a custom struct gives me the following error. -

**ERROR**

keyNotFound(CodingKeys(stringValue: "artistName", intValue: nil), Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "data", intValue: nil), _JSONKey(stringValue: "Index 20", intValue: 20), CodingKeys(stringValue: "attributes", intValue: nil)], debugDescription: "No value associated with key CodingKeys(stringValue: \"artistName\", intValue: nil) (\"artistName\").", underlyingError: nil))

The data couldn’t be read because it is missing.

On digging through the response, I found that one of the songs doesn't have an artist name because it is just a recording of my song I added to the library through GarageBand.

In this case, what should be the approach?

Answered by Frameworks Engineer in 688543022

Hello @snuff4,

We have included a fix for this issue in iOS 15.1 Beta 1.

I hope this helps.

Best regards,

Hello @snuff4,

Would you mind showing your custom struct?

Thanks,

Hi @JoeKun,

This is the custom struct -

struct Songs: Decodable {
  let data: [Song]
}

where Song is the new structure in MusicKit for Swift.

Hi @snuff4,

This is a bug we need to address on our end. Can you file a ticket for this on Feedback Assistant?

Thanks,

Hi @JoeKun, While creating my own framework for easy access to different Apple Music APIs, I realized I was using it wrong. It's better to decode using MusicItemCollection<> instead of creating my own structure. Then, it safely ignores the item that is not decodable due to missing information.

let response = try JSONDecoder().decode(MusicItemCollection<Song>.self, from: dataResponse.data)

Hello @snuff4,

Interesting. I knew using MusicItemCollection<Song> instead of a custom struct for simple cases like these was a good alternative; for example, it allows apps to leverage MusicItemCollection builtin support for pagination to get the next batch of items.

However, I didn't remember that it would ignore problematic items like this. Thanks for sharing the tip!

Best regards,

Accepted Answer

Hello @snuff4,

We have included a fix for this issue in iOS 15.1 Beta 1.

I hope this helps.

Best regards,

Cannot decode library songs response for a non-Apple Music item
 
 
Q