i created one and it says it has identified a fix, but so far is not fixed in iOS18.01. This breaks my entire app. Here is the report ID FB15179078 (MusicKit Queue broke in iOS18, it won't queue all the songs.).
Post
Replies
Boosts
Views
Activity
iOS18 bug. If you have that song already in your library, it will stop queuing at that point. One of my frustrations with APPLE API's in general, they have bugs and you wait till they fix it, you expect them to be pretty solid on stuff as simple as queuing songs, but it absolutely breaks the entire point of the API, which is to queue songs to play!
import MusicKit
struct ContentView: View {
var body: some View {
VStack{
Button("Play Music") {
Task{
await playMusic()
}
}
}
}
}
func fetchPlaylist(withID playlistID: String) async -> Playlist? {
do {
// Create a request for the playlist resource
let request = MusicCatalogResourceRequest<Playlist>(matching: \.id, equalTo: MusicItemID(playlistID))
// Perform the request
let response = try await request.response()
// Access the fetched playlist
if let playlist = response.items.first {
print("Playlist Title: \(playlist.name)")
print("Tracks Count: \(playlist.tracks?.count)")
return playlist
} else {
print("Playlist not found")
return nil
}
} catch {
print("Error fetching playlist: \(error.localizedDescription)")
}
return nil
}
func getOnlySongsFromTracks(tracks:MusicItemCollection<Track>?) async throws ->MusicItemCollection<Song>?{
var songs:[Song]?
if let t = tracks{
songs = [Song]()
for track in t {
if case let .song(song) = track {
songs?.append(song)
print("track is song \(track.debugDescription)")
}else{
print("track not song \(track.debugDescription)")
}
}
}
if let songs = songs {
let topSongs = MusicItemCollection(songs)
return topSongs
}
return nil
}
func playMusic() async {
// Request authorization
let status = await MusicAuthorization.request()
guard status == .authorized else {
print("Music authorization denied.")
return
}
do {
// Perform a hardcoded search for a playlist
let searchTerm = "2000"
let request = MusicCatalogSearchRequest(term: searchTerm, types: [Playlist.self])
let response = try await request.response()
guard let playlist = response.playlists.first else {
print("No playlists found for the search term '\(searchTerm)'.")
return
}
print("playlist id \(playlist.id)")
// Fetch the songs in the playlist
guard let playlistHardcoded = await fetchPlaylist(withID: "pl.e50ccee7318043eaaf8e8e28a2a55114") else{
return
}
let detailedPlaylist = try await playlistHardcoded.with([.tracks])
guard let songCollection = try await getOnlySongsFromTracks(tracks: detailedPlaylist.tracks) else {
print("no songs found")
return }
guard let t = detailedPlaylist.tracks else {
print("no tracks")
return
}
// Create a queue and play
let musicPlayer = ApplicationMusicPlayer.shared
let q = ApplicationMusicPlayer.Queue(for: t)
musicPlayer.queue = q
try await musicPlayer.play()
print("Now playing playlist: \(playlist.name)")
} catch {
print("An error occurred: \(error.localizedDescription)")
}
}
I've did a few tests, it only updates on Mac when you play the entire song.
When i play the entire song on iOS (17) now, it does not update the count on the Song.playCount property. Hey Apple, if you don't update it, why are you signaling that in the API that it works for iOS? This is wasting developer time testing.
Also this:
`2023-01-22 00:00:35.425636-0500 MusicApp1[6285:1007618] [core] Attempted to register account monitor for types client is not authorized to access: {(
"com.apple.account.iTunesStore"`
One thing I want to add is that if the API's data changes so often, it's very difficult to create apps for it as there is always BIG RISKS that the API can change and degrade an app or even disable it all together. Maybe more transparency or promises of what will be affected and give time instead of just changing it on whims would really help us out.
Thanks