Q:

Fastest way to retrieve meta information from ios Media Library?

I'm trying to retrieve meta information from the ios media library and then send it to the server in json.
However, I found that looping through the MPMediaQuery result and pulling the meta information to be very slow.
MPMediaQuery *query = [[MPMediaQuery alloc]init];
MPMediaPropertyPredicate *predicate = [MPMediaPropertyPredicate predicateWithValue:[NSNumber numberWithInteger:MPMediaTypeMusic] forProperty:MPMediaItemPropertyMediaType];
[query addFilterPredicate:predicate];

NSMutableArray *songs = [[NSMutableArray alloc] init];
songs = [query items];

[songs enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
    [obj valueForProperty:MPMediaItemPropertyTitle];
    [obj valueForProperty:MPMediaItemPropertyPlaybackDuration];
    [obj valueForProperty:MPMediaItemPropertyArtist];
    [obj valueForProperty:MPMediaItemPropertyAlbumTitle];
    [obj valueForProperty:MPMediaItemPropertyGenre];
    [obj valueForProperty:MPMediaItemPropertyAlbumTrackNumber];
}];

For a library of 9000 songs, it can take upwards of 25 seconds to finish the enumeration loop.
Is there a faster way to retrieve the meta information in bulk? ValueForProperty seem very inefficient in this case (each call in the loop adds about 5 seconds).

A:

The docs for MPMediaItem state that using enumerateValuesForProperties:usingBlock: is usually faster than making individual calls to valueForProperty:. Try this:
NSSet *properties = [NSSet setWithArray:@[ MPMediaItemPropertyTitle, MPMediaItemPropertyPlaybackDuration, MPMediaItemPropertyArtist,  MPMediaItemPropertyAlbumTitle, MPMediaItemPropertyGenre, MPMediaItemPropertyAlbumTrackNumber ]];

[songs enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
    MPMediaItem *item = (MPMediaItem *)obj;
    [item enumerateValuesForProperties:properties usingBlock:^(NSString *property, id value, BOOL *stop) {
        // do something with this property / value pair
    }];
}];

