swift3mpmusicplayercontrollermpmediaquery

Need good explanation of MPMediaQuery results for collections and items


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:

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?


Solution

  • 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()