我正在尝试使用MPMediaQuery
访问用户的本地音乐库,以便按以下方式对结果进行排序:
Artist A (sorted alphabetically) > All of Artist A's albums, sorted alphabetically
Artist B (sorted alphabetically) > All of Artist B's albums, sorted alphabetically
Artist C (sorted alphabetically) > All of Artist C's albums, sorted alphabetically
...
我的查询结构如下:
MPMediaQuery *albumsQuery = [MPMediaQuery albumsQuery];
albumsQuery.groupingType = MPMediaGroupingAlbumArtist;
但问题在于,虽然上述内容大多有效,但每位特定艺术家的仅首张专辑会被退回。也就是说,只返回Alt-J的一个专辑,而不是库中存在的两个专辑。
为什么?如何构造我的查询以返回所需的结果?
编辑:这就是我访问albumsQuery的方式:
AlbumCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:CellID forIndexPath:indexPath];
MPMediaItemCollection *collection = [_items objectAtIndex:indexPath.row];
MPMediaItem *cellItem = [collection representativeItem];
_items
是一个包含MPMediaQuery
结果的NSArray。
答案 0 :(得分:4)
似乎David Barsky的算法在使用大型库时非常慢。我采取了不同的方法:
-(NSArray *)albumsSortedByArtist
{
CFTimeInterval start = CACurrentMediaTime();
MPMediaQuery *albumsQuery = [MPMediaQuery albumsQuery];
NSSortDescriptor *sorter = [NSSortDescriptor sortDescriptorWithKey:@"representativeItem"
ascending:YES comparator:^NSComparisonResult(MPMediaItem * _Nonnull album1, MPMediaItem * _Nonnull album2) {
NSString *album1Name = [album1 valueForProperty:MPMediaItemPropertyAlbumArtist];
NSString *album2Name = [album2 valueForProperty:MPMediaItemPropertyAlbumArtist];
if (!album1Name || !album2Name) {
album1Name = [album1 valueForProperty:MPMediaItemPropertyArtist];
album2Name = [album2 valueForProperty:MPMediaItemPropertyArtist];
}
return [album1Name localizedStandardCompare:album2Name];
}];
NSArray *allAlbums = [albumsQuery.collections sortedArrayUsingDescriptors:@[sorter]];
NSLog(@"It took %f", CACurrentMediaTime() - start);
return allAlbums;
}
它快得多。在iPhone 6库上有1161张专辑:
2016-06-07 20:28:51.620 Musica[1205:515625] Mine: 0.394556
2016-06-07 20:29:20.528 Musica[1205:515625] David Barsky's: 28.906980
答案 1 :(得分:0)
您是如何从查询中访问相册的?有条款方法,或者,如果我没记错的话,收集方法。他们如何为您提供数据有点不同。
显然你可以自己动手制作,只需获取所有相册的清单并自行分类!
编辑I:按专辑艺术家分组意味着该系列为您提供每个专辑艺术家,然后获得代表性项目基本上只是一个专辑。因此,您需要对该集合进行另一次查询,以获取该艺术家的每张专辑
编辑II:您可以使用您已经找到的内容来进行其他查询,例如,您已经获得的是所有不同专辑艺术家的集合。您想知道每位艺术家的专辑是什么,以便您可以使用其他谓词重复查询:
MPMediaItem * albumArtist; //以前采购过 MPMediaQuery * albumQuery = [MPMediaQuery albumsQuery]; MPMediaPropertyPredicate * albumPredicate = [MPMediaPropertyPredicate predicateWithValue:[albumArtist valueForProperty:MPMediaItemPropertyAlbumArtist] forProperty:MPMediaItemPropertyAlbumArtist]; [albumQuery addFilterPredicate:albumPredicate]; NSArray * allAlbums = [albumQuery collections];
答案 2 :(得分:0)
以下作品(慢慢地,在相当大的音乐库上。您的结果可能会有所不同)。积分可以CMash获得帮助。
- (NSArray *)queryForMusic {
NSMutableArray *allAlbums = [[NSMutableArray alloc] init];
MPMediaQuery *artistsQuery = [MPMediaQuery artistsQuery];
artistsQuery.groupingType = MPMediaGroupingAlbumArtist;
NSArray *allArtists = [artistsQuery collections];
for (MPMediaItemCollection *collection in allArtists) {
MPMediaItem *albumArtist = [collection representativeItem];
MPMediaQuery *albumQuery = [MPMediaQuery albumsQuery];
MPMediaPropertyPredicate* albumPredicate = [MPMediaPropertyPredicate predicateWithValue: [albumArtist valueForProperty: MPMediaItemPropertyAlbumArtist] forProperty: MPMediaItemPropertyAlbumArtist];
[albumQuery addFilterPredicate: albumPredicate];
NSArray *artistsAblums = [albumQuery collections];
[allAlbums addObjectsFromArray:artistsAblums];
}
return allAlbums;
}