Question

I'm trying to get a list of all the Video items in a user's iPhone library, and have them sorted by Album Name first, and then by Track Number (on the idea that this will put all the TV Shows and Podcasts in the proper show/episode order). Thing is, I can't figure out a way to sort MPMediaItems by two parameters like that.

Right now, I set the query like this:

MPMediaPropertyPredicate *predicate = [MPMediaPropertyPredicate predicateWithValue:[NSNumber numberWithInteger:MPMediaTypeAnyVideo] forProperty:MPMediaItemPropertyMediaType];

MPMediaQuery *query = [[MPMediaQuery alloc] init];
[query addFilterPredicate:predicate];

NSArray *arrayMediaItems = [[NSArray alloc] init];
arrayMediaItems = [query items];

and then I sort it like this:

NSArray *sortedArray = [arrayMediaItems sortedArrayUsingComparator:^(id a, id b) {
    NSNumber *first = [(MPMediaItem*)a valueForProperty:MPMediaItemPropertyAlbumTitle];
    NSNumber *second = [(MPMediaItem*)b valueForProperty:MPMediaItemPropertyAlbumTitle];
    return [first compare:second];
}];

Thing is, that returns a list where all the Albums (read: shows) are in the right order, but the episodes within them are just alphabetized, which is obviously not right. I tried doing this instead:

NSSortDescriptor *sortAlbum = [[NSSortDescriptor alloc] initWithKey:@"MPMediaItemPropertyAlbumTitle" ascending:YES];
NSSortDescriptor *sortTrackNum = [[NSSortDescriptor alloc] initWithKey:@"MPMediaItemPropertyAlbumTrackNumber" ascending:YES];
NSArray *sortDescriptors = @[sortAlbum, sortTrackNum];
sortedArray = [arrayMediaItems sortedArrayUsingDescriptors:sortDescriptors];

but I get an error: this class is not key value coding-compliant for the key MPMediaItemPropertyAlbumTitle. As I understand it, this is because I'm trying to sort by properties instead of keys.

So my question is this: how does one sort MPMediaItems by multiple factors? Could I order the initial results (e.g. by Track Number instead of alphabetized by Title), and then just sort it by Album Name? Is there a way to use NSSortDescriptor or sortedArrayUsingComparator with two dimensions?

What's the best way to do this?

Was it helpful?

Solution 2

I ended up finding a code sample from this question. I'm working with a lot fewer than 1,200 items, so either the code in the question or the answer would work for me, but I used the one in the answer for efficiency. (It also uses MPMediaItemPropertyAlbumPersistentID in addition to the album title, which I like as a check against albums/shows with the same title.)

sortedArray = [arrayMediaItems sortedArrayUsingComparator:^NSComparisonResult(id a, id b) {
    NSComparisonResult compareResult;

    NSString *first1 = [(MPMediaItem*)a valueForProperty:MPMediaItemPropertyAlbumTitle];
    if(first1 == nil) first1 = @" "; // critical because compare will match nil to anything and result in NSOrderedSame
    NSString *second1 = [(MPMediaItem*)b valueForProperty:MPMediaItemPropertyAlbumTitle];
    if(second1 == nil) second1 = @" ";  // critical because compare will match nil to anything and result in NSOrderedSame
    compareResult = [first1 compare:second1];

    if (compareResult == NSOrderedSame) {
        NSString *first2 = [(MPMediaItem*)a valueForProperty:MPMediaItemPropertyAlbumPersistentID];
        NSString *second2 = [(MPMediaItem*)b valueForProperty:MPMediaItemPropertyAlbumPersistentID];
        compareResult = [first2 compare:second2];
        if(compareResult == NSOrderedSame) {
            NSString *first3 = [(MPMediaItem*)a valueForProperty:MPMediaItemPropertyAlbumTrackNumber];
            NSString *second3 = [(MPMediaItem*)b valueForProperty:MPMediaItemPropertyAlbumTrackNumber];
            compareResult = [first3 compare:second3];
        }
    }
    return compareResult;
}];

I hope this helps someone!

OTHER TIPS

Consider this as a comment. Because I couldn't post images there.

enter image description here

enter image description here

The above images are screenshots for MediaPlayer framework Constants. Your says there is no property likes "MPMediaItemPropertyAlbumTitle" and "MPMediaItemPropertyAlbumTrackNumber". Because they are constants for some other properties.

Try albumTitleand albumTrackNumber instead of "MPMediaItemPropertyAlbumTitle" and "MPMediaItemPropertyAlbumTrackNumber"

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top