3

I need some help in understanding MPMediaQuery and how to access the results so that I can use the query with setQueue(with:).

Here's an example of why I am confused.

In my library I have an artist with 3 albums. My goal is a query for those 3 albums, in order with each track in order:

  • Album A
    • track 1
    • track 2
    • track 3
  • Album 2
    • track 1
    • track 2
    • track 3
  • Album 3
    • track 1
    • track 2
    • track 3

When I use this query, the Albums/songs are not in order as expected. They almost appear shuffled even though shuffle is NOT on.

var qryArtists = MPMediaQuery()
qryArtists = MPMediaQuery.artists()
qryArtists.groupingType = MPMediaGrouping.albumArtist
let currLoc = qryArtists.collectionSections![indexPath.section].range.location
myMP.setQueue(with: qryArtists.collections![indexPath.row + currLoc])
for junk in qryArtists.collections![indexPath.row + currLoc].items{
    print(" collections title \(junk.albumTitle!) track \(junk.albumTrackNumber) song \(junk.title!)")
}

I get these results:

collections title Cosmic Thing track 8 song Channel Z collections title Cosmic Thing track 1 song Cosmic Thing collections title Wild Planet track 6 song Devil In My Car collections title Wild Planet track 2 song Dirty Back Road collections title Wild Planet track 4 song Give Me Back My Man collections title Cosmic Thing track 5 song June Bug collections title Wild Planet track 1 song Party Out Of Bounds collections title Wild Planet track 5 song Private Idaho collections title Wild Planet track 7 song Quiche Lorraine collections title Cosmic Thing track 6 song Roam collections title The B-52's track 15 song Rock Lobster collections title Wild Planet track 3 song Runnin' Around collections title Wild Planet track 8 song Strobe Light collections title Cosmic Thing track 9 song Topaz collections title Wild Planet track 9 song 53 Miles West Of Venus

Notice the Albums/Songs are not in proper order

However, if I use this print statement instead I get expected results:

for junk in newQry.items!{
    print("items title \(junk.albumTitle!) track \(junk.albumTrackNumber) song \(junk.title!)")
}

Results:

items title The B-52's track 15 song Rock Lobster items title Cosmic Thing track 1 song Cosmic Thing items title Cosmic Thing track 5 song June Bug items title Cosmic Thing track 6 song Roam items title Cosmic Thing track 8 song Channel Z items title Cosmic Thing track 9 song Topaz items title Wild Planet track 1 song Party Out Of Bounds items title Wild Planet track 2 song Dirty Back Road items title Wild Planet track 3 song Runnin' Around items title Wild Planet track 4 song Give Me Back My Man items title Wild Planet track 5 song Private Idaho items title Wild Planet track 6 song Devil In My Car items title Wild Planet track 7 song Quiche Lorraine items title Wild Planet track 8 song Strobe Light items title Wild Planet track 9 song 53 Miles West Of Venus

Also, another very strange effect: If I set the MusicPlayer query:

myMP.setQueue(with: newQry)

and then issue the SAME 'items' print statement, the results are now mixed in the exact same way as the 'collections' version!

Why would setting the queue change the way the query behaves?

Since I can't setQueue with newQry.items, how can I build a queue to get the Albums and Songs in expected order?

wayneh
  • 4,393
  • 9
  • 35
  • 70

2 Answers2

6

OK, I solved this myself with a lot more research. The trick here is to use the ITEMS which are sorted correctly, and build a new Collection to use as the queue.

All it takes is that addition of a single line of code:

let collection = MPMediaItemCollection(items: newQry.items!)

and then a change to the setQueue function:

myMP.setQueue(with: collection)

Here's the final working code block - compare to my original post OP above:

    let newQry = MPMediaQuery.albums()
    newQry.addFilterPredicate(
        MPMediaPropertyPredicate(
            value: artistArray[indexPath.row + currLoc],
            forProperty: MPMediaItemPropertyAlbumArtist,
            comparisonType: .equalTo
        )
    )
    //build a new collection with the sorted items then load the collection!
    let collection = MPMediaItemCollection(items: newQry.items!)
    myMP.stop()
    myMP.setQueue(with: collection)
    myMP.play()
wayneh
  • 4,393
  • 9
  • 35
  • 70
  • I am very sad because I have not found useful information about MPMediaQuery (beyond that provided by Apple). I am looking for sample code to understand how to use MPMediaQuery. THANK YOU VERY MUCH FOR YOUR CODE. I am trying to create a TableView with all the artists in my music library. Select an artist and get all the artist's albums or songs. Anyway... – Markus May 06 '20 at 13:55
  • You're welcome - I hope the code works for you. You are right - there is a severe lack of sample code out there for this kind of thing. Code for dealing with Podcasts is even more limited. Good luck. – wayneh May 06 '20 at 17:27
  • Well I'm still trying to create a TableView with the artists from my library (iPhone), as Apple music app. I begin to understand that the first step is to create a collection, and then manage it to get the results. The problem I have is the syntax. In Swift (as in all languages) a misspelled word and everything fails. I've lost so many hours... – Markus May 07 '20 at 10:06
0

All MPMediaQuery does is query the existing database located at:

\Users\your_username\Music\Music\Music Library.musiclibrary

That file is automatically generated by adding music to the local Apple Music app on each individual computer.

It does not communicate with Apple's servers, so it will never show past iTunes purchases or items in the cloud that do not exist in the Apple Music app on the computer you are using.

If you delete an album from your local Apple Music app, it is removed from the Music Library.musiclibrary database.

That album still exists on Apple's servers, tied to your Apple account. You may still download that album again using the iTunes Store. However, MPMediaQuery can no longer query that album because it doesn't exist on your local computer.

Michael N
  • 436
  • 5
  • 6