Post

Replies

Boosts

Views

Activity

Reply to MusicLibraryRequest to get all tracks from a playlist (iOS 16 beta)
I've been trying to get better at structured concurrency, so I took a stab at a function that collects all of the tracks from a library playlist. I think the key here is using the hasNextBatch property on MusicItemCollection. I'm far from on expert in this world, so I'm sure this code can be improved. In the meantime, here's what I came up with. It correctly returns the number of songs on playlists with more than 100 songs.    func getTracksFromPlaylist(name: String) async throws {         var request = MusicLibraryRequest<Playlist>.init()         request.filter(text: name)         let result = try! await request.response()         if let first = result.items.first {             let withTracks = try await first.with(.tracks)             guard let startingTracks = withTracks.tracks else {                 return             }                       try await getAllTracksFromPlaylist(startingTracks: startingTracks, group: nil)         }     }      func getAllTracksFromPlaylist(startingTracks: MusicItemCollection<Track>, group: ThrowingTaskGroup<[Track],Error>?) async throws  { //If the group didn't come in as nil, that means startingTracks has a next batch that needs to be fetched and processed         if var group = group {                 if let currentSetToProcess = try await startingTracks.nextBatch() { //Add the tracks from this batch to the group                      group.addTask {                         return Array(currentSetToProcess)                     } //If this set has a next batch, run the function again. Once currentSetToProcess.hasNextBatch returns false, the group will complete since it is not awaiting anything else.                     if currentSetToProcess.hasNextBatch {                        try await getAllTracksFromPlaylist(startingTracks: currentSetToProcess, group: group)                     }                 }            //If the group came in as nil, create the group and work through the first batch of tracks.         } else {             try await withThrowingTaskGroup(of: [Track].self, body: { group in //The array to store the final set of tracks                 var allTracks: [Track] = []               //Add the starting tracks to the group                 group.addTask {                     return Array(startingTracks)                 } //If there are more than 100 tracks on the playlist, this is true and means we need to loop through and get the other tracks.                 if startingTracks.hasNextBatch {                     try await getAllTracksFromPlaylist(startingTracks: startingTracks, group: group)                 }                                  //As arrays of tracks are added to the group, append them to our allTracks array.                 for try await tracks in group {                     allTracks.append(contentsOf: tracks)                 }           //Finally, when the group has returned all of the tracks, print the final amount.                 print(allTracks.count)                   })         }     }
Topic: Media Technologies SubTopic: General Tags:
Jun ’22
Reply to Thoughts on MusicLibraryRequest as a replacement for MPMediaQuery
Thanks, @JoeKun! My bad -- yes, I suppose just because they aren't the key paths I want doesn't mean they aren't key paths to begin with ;) I guess the proper request is something like: please add the following properties to the following protocols to enable more specific filtering in MusicLibraryRequests: LibrarySongFilter albumTitle artistName composerName title LibraryAlbumFilter artistName title LibraryArtistFilter name
Topic: Media Technologies SubTopic: General Tags:
Jun ’22
Reply to Is the MusicItemID different per locale?
It turns out that ids are different across different catalog locales, but there is an easy way in the API to find equivalent items. That's actually the first topic covered in this WWDC session from last year: https://developer.apple.com/wwdc21/10293. If I were you, I'd be cautious about caching that id information, or at least making sure you gracefully handle the case where an item is no longer accessible at the id you have saved for it. I've seen a handful of cases in my own app where an album's id changes for whatever reason.
Topic: Media Technologies SubTopic: General Tags:
Mar ’22
Reply to Accessing details about the Curator
I haven't played around at all with the curator stuff -- @JoeKun, that post is a great overview and has me playing around in Postman. One thing I haven't been able to figure out: is there any particular rhyme or reason to the order in which the API returns the Playlist relationships? Taking your example of Apple Music Pop, I had expected the API to return the playlists in an order roughly equivalent to the page in Music.app. The most popular playlists first, which as I look now at Music.app on my Mac are "Today's Hits" and "Viral Hits." These are the two playlists returned from this endpoint, which I don't see anywhere on the Music.app Apple Music Pop page: "name": "Tom Mann: Songbook", "url": "https://music.apple.com/us/playlist/tom-mann-songbook/pl.b5a5fecc589d4056be182e8cafdc0fc0" and "url": "https://music.apple.com/us/playlist/ivan-dorn-essentials/pl.362b70aa54e54989a08a2e2df4ff48d3", "name": "Ivan Dorn Essentials", The Albums relationship for Artist seems to be more or less by popularity, but that doesn't seem to be the case here. Any hints at how to best make use of that resource?
Topic: Media Technologies SubTopic: General Tags:
Mar ’22
Reply to MusicKit play back with Mac Catalyst seems not be working.
I filed feedback FB9851840 (including sample project) reporting this very issue just moments before seeing this post. I get the same error as you. The documentation page for MusicPlayer does not mention it is available in macOS, but says it is in Mac Catalyst 15.0+, so it's not clear what is supposed to work. Perhaps @JoeKun can shed some light on the expected behavior of this API? I am really hoping to bring my iOS music player to the Mac in the future.
Topic: Media Technologies SubTopic: General Tags:
Jan ’22
Reply to MusicLibraryRequest to get all tracks from a playlist (iOS 16 beta)
I've been trying to get better at structured concurrency, so I took a stab at a function that collects all of the tracks from a library playlist. I think the key here is using the hasNextBatch property on MusicItemCollection. I'm far from on expert in this world, so I'm sure this code can be improved. In the meantime, here's what I came up with. It correctly returns the number of songs on playlists with more than 100 songs.    func getTracksFromPlaylist(name: String) async throws {         var request = MusicLibraryRequest<Playlist>.init()         request.filter(text: name)         let result = try! await request.response()         if let first = result.items.first {             let withTracks = try await first.with(.tracks)             guard let startingTracks = withTracks.tracks else {                 return             }                       try await getAllTracksFromPlaylist(startingTracks: startingTracks, group: nil)         }     }      func getAllTracksFromPlaylist(startingTracks: MusicItemCollection<Track>, group: ThrowingTaskGroup<[Track],Error>?) async throws  { //If the group didn't come in as nil, that means startingTracks has a next batch that needs to be fetched and processed         if var group = group {                 if let currentSetToProcess = try await startingTracks.nextBatch() { //Add the tracks from this batch to the group                      group.addTask {                         return Array(currentSetToProcess)                     } //If this set has a next batch, run the function again. Once currentSetToProcess.hasNextBatch returns false, the group will complete since it is not awaiting anything else.                     if currentSetToProcess.hasNextBatch {                        try await getAllTracksFromPlaylist(startingTracks: currentSetToProcess, group: group)                     }                 }            //If the group came in as nil, create the group and work through the first batch of tracks.         } else {             try await withThrowingTaskGroup(of: [Track].self, body: { group in //The array to store the final set of tracks                 var allTracks: [Track] = []               //Add the starting tracks to the group                 group.addTask {                     return Array(startingTracks)                 } //If there are more than 100 tracks on the playlist, this is true and means we need to loop through and get the other tracks.                 if startingTracks.hasNextBatch {                     try await getAllTracksFromPlaylist(startingTracks: startingTracks, group: group)                 }                                  //As arrays of tracks are added to the group, append them to our allTracks array.                 for try await tracks in group {                     allTracks.append(contentsOf: tracks)                 }           //Finally, when the group has returned all of the tracks, print the final amount.                 print(allTracks.count)                   })         }     }
Topic: Media Technologies SubTopic: General Tags:
Replies
Boosts
Views
Activity
Jun ’22
Reply to Thoughts on MusicLibraryRequest as a replacement for MPMediaQuery
Thanks, @JoeKun! My bad -- yes, I suppose just because they aren't the key paths I want doesn't mean they aren't key paths to begin with ;) I guess the proper request is something like: please add the following properties to the following protocols to enable more specific filtering in MusicLibraryRequests: LibrarySongFilter albumTitle artistName composerName title LibraryAlbumFilter artistName title LibraryArtistFilter name
Topic: Media Technologies SubTopic: General Tags:
Replies
Boosts
Views
Activity
Jun ’22
Reply to Is the MusicItemID different per locale?
It turns out that ids are different across different catalog locales, but there is an easy way in the API to find equivalent items. That's actually the first topic covered in this WWDC session from last year: https://developer.apple.com/wwdc21/10293. If I were you, I'd be cautious about caching that id information, or at least making sure you gracefully handle the case where an item is no longer accessible at the id you have saved for it. I've seen a handful of cases in my own app where an album's id changes for whatever reason.
Topic: Media Technologies SubTopic: General Tags:
Replies
Boosts
Views
Activity
Mar ’22
Reply to Accessing details about the Curator
I haven't played around at all with the curator stuff -- @JoeKun, that post is a great overview and has me playing around in Postman. One thing I haven't been able to figure out: is there any particular rhyme or reason to the order in which the API returns the Playlist relationships? Taking your example of Apple Music Pop, I had expected the API to return the playlists in an order roughly equivalent to the page in Music.app. The most popular playlists first, which as I look now at Music.app on my Mac are "Today's Hits" and "Viral Hits." These are the two playlists returned from this endpoint, which I don't see anywhere on the Music.app Apple Music Pop page: "name": "Tom Mann: Songbook", "url": "https://music.apple.com/us/playlist/tom-mann-songbook/pl.b5a5fecc589d4056be182e8cafdc0fc0" and "url": "https://music.apple.com/us/playlist/ivan-dorn-essentials/pl.362b70aa54e54989a08a2e2df4ff48d3", "name": "Ivan Dorn Essentials", The Albums relationship for Artist seems to be more or less by popularity, but that doesn't seem to be the case here. Any hints at how to best make use of that resource?
Topic: Media Technologies SubTopic: General Tags:
Replies
Boosts
Views
Activity
Mar ’22
Reply to MusicKit play back with Mac Catalyst seems not be working.
I filed feedback FB9851840 (including sample project) reporting this very issue just moments before seeing this post. I get the same error as you. The documentation page for MusicPlayer does not mention it is available in macOS, but says it is in Mac Catalyst 15.0+, so it's not clear what is supposed to work. Perhaps @JoeKun can shed some light on the expected behavior of this API? I am really hoping to bring my iOS music player to the Mac in the future.
Topic: Media Technologies SubTopic: General Tags:
Replies
Boosts
Views
Activity
Jan ’22