Hi @JoeKun, thanks for the response.
I did try something similar to the above with MusicDataRequest ; however, as I'm doing a POST, I needed to also send a body. And I was getting errors, which had me thinking that the problem was potentially with MusicDataRequest.
Any further help to get this working, would be much appreciated.
The below code throws the following error:
MusicDataRequest.Error(
status: 400,
code: 40007,
title: "Invalid Request Body",
detailText: "Unable to parse request body",
id: "CKYZ347O6YJDXVPVSTZJOQ4R6Y",
originalResponse: MusicDataResponse(
data: 149 bytes,
urlResponse: <NSHTTPURLResponse: 0x0000000283e9ed00>
)
)
Please see comments within the below:
func addTracksToAppleMusicPlaylist(targetPlaylistId: String, tracksToAdd: [Song]) async throws -> Void {
struct AppleMusicPlaylistPostRequestItem: Codable {
let id: MusicItemID
let type: String
}
// This is what I have done using when updating a playlist in a JS app (but without the type)
// My guess is that the problem is with the encoded data
let tracks = tracksToAdd.compactMap{
AppleMusicPlaylistPostRequestItem(id: $0.id, type: "songs")
}
do {
print("Saving matched tracks to Apple Music Playlist: \(targetPlaylistId)")
if let url = URL(string: "https://api.music.apple.com/v1/me/library/playlists/\(targetPlaylistId)/tracks") {
var urlRequest = URLRequest(url: url)
urlRequest.httpMethod = "POST"
let encoder = JSONEncoder()
let data = try encoder.encode(tracks)
print(String(data: data, encoding: .utf8)!) // <== See result below.
urlRequest.httpBody = data // <== This is most likey the problem!
let musicRequest = MusicDataRequest(urlRequest: urlRequest)
let musicRequestResponse = try await musicRequest.response()
// maybe do something with response once I get this working...
} else {
print("Bad URL!")
throw AddToPlaylistError.badUrl(message: "Bad URL!")
}
} catch {
print("Error Saving Tracks to Playlist", error)
throw error
}
}
The output from that print command, above, looks like this, which seems right:
[{"id":"426656373","type":"songs"},{"id":"1559839880","type":"songs"},{"id":"1498420189","type":"songs"}]
I've made some progress here and am drawing some assumptions, which I hope to get verified in this thread.
Assumption #1: MusicDataRequest() doesn't support POST requests. I tried many different ways to do this and kept getting parsing errors when trying to pass an encoded data object in the body.
So I gave up on using MusicDataRequest and went "old school" with the below.
Assumption #2: As the below code results in a 400 (bad request) status and there is no additional information in the response, I assume there is something wrong with the request, most likely a bad request.httpBody entry.
The below is, as best I can code in Swift right now, the same call I make in a JS app.
`func addTracksToAppleMusicPlaylist(targetPlaylistId: String, tracksToAdd: [AppleMusicTracks]) async throws -> Void { let tracks = tracksToAdd.compactMap{ AppleMusicPlaylistPostRequest(id: $0.id, type: "songs") } do { print("Saving tracks to Apple Music Playlist: (targetPlaylistId)") let tokens = try await self.getAppleMusicTokens() // <-this works correctly
if let url = URL(string: "https://api.music.apple.com/v1/me/library/playlists/%5C(targetPlaylistId)/tracks") { var request = URLRequest(url: url) request.httpMethod = "POST" request.addValue("Bearer (tokens.devToken)", forHTTPHeaderField: "Authorization") request.addValue("(tokens.userToken)", forHTTPHeaderField: "Music-User-Token") request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type") let encoder = JSONEncoder() let data = try encoder.encode(tracks) request.httpBody = data let session = URLSession(configuration: .default) let task = session.dataTask(with: request) {(data, response, error) in if error == nil { if let httpResponse = response as? HTTPURLResponse { print("statusCode: (httpResponse.statusCode)") print("response: (httpResponse)"). // <= 400 response here } } else { print("Error saving tracks to playlist (String(describing: error))") } } task.resume() } else { print("Bad URL!") } } catch { print("Error Saving Tracks to Playlist", error) throw error } }`