Some time around or before September 2022, the MPMediaQuery stopped working for AppleMusic songs using their persistentID. This used to work and no longer does. I'm on XCode 15.1, iOS 17.2.1
All other lookups by persistentId succeed for local assets, things bought with the Music app, etc.
Steps to reproduce:
- Sign up for Apple Music
- Find "Tom Sawyer" by Rush, add this song to your library.
- Verify the song is in your library -> open the "Music" app, and go to "Playlists" and verify the song is in the "Apple Music" playlist.
- Use the MPMediaPickerController in your 3rd party app to select this song from the Apple Music Playlist.
- Use MPMediaQuery to lookup this song using its
persistentID. - Notice the empty result from the MPMediaQuery.
Here is some sample code for the mediaPicker: didPickMediaItems callback:
@objc func mediaPicker(_ mediaPicker: MPMediaPickerController, didPickMediaItems collection: MPMediaItemCollection) {
print("Songs: \(collection.items)")
var foundNumber = 0
collection.items.forEach { song in
if let foundSong = MPMediaItem.findOne(fromPersistentId: Int64(song.persistentID)) {
foundNumber += 1
} else {
print("Could not find song with MPMediaQuery: \(String(describing: song.title)), persistentId: \(song.persistentID), cloud: \(song.isCloudItem), protected: \(song.hasProtectedAsset)")
}
}
print("Found \(foundNumber) songs out of \(collection.items.count) from the MPMediaPickerController using MPMediaQuery and the persistentId.")
}
Here is the extension function to lookup the song with an MPMediaQuery that works for all songs except Apple Music songs:
import Foundation
import MusicKit
import MediaPlayer
extension MPMediaItem {
internal static func findOne(fromPersistentId persistentId: Int64) -> MPMediaItem? {
// Try to look up with Key: MPMediaItemPropertyPersistentID, value: string or int64 persistentId
return MPMediaItem.findOne(value: persistentId.toString(), forProperty: MPMediaItemPropertyPersistentID)
}
internal static func findOne(value: Any, forProperty property: String) -> MPMediaItem? {
let predicate = MPMediaPropertyPredicate(value: value, forProperty: property)
let query = MPMediaQuery()
query.addFilterPredicate(predicate)
if (query.items?.count ?? 0) > 0 {
if let items = query.items {
if items.count >= 1 {
return items[0]
}
}
}
return nil
}
}
private extension Int64 {
func toString() -> String { return String(format: "%llu", self) }
}
What I've tried:
- I've tried searching around for similarly reported issues. There is nothing I've found related to this not working only for these types of songs.
- Created a sample application to reproduce the issue. (can send if requested)
- Tried a different device.