使用 MPMediaQuery 按艺术家对专辑进行排序
Posted
技术标签:
【中文标题】使用 MPMediaQuery 按艺术家对专辑进行排序【英文标题】:Sort Albums by Artist using MPMediaQuery 【发布时间】:2015-03-21 20:01:47 【问题描述】:我正在尝试使用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 的一张专辑,而不是库中存在的两张专辑。
这是为什么呢?以及如何构造我的查询以返回所需的结果?
编辑:这是我访问相册查询的方式:
AlbumCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:CellID forIndexPath:indexPath];
MPMediaItemCollection *collection = [_items objectAtIndex:indexPath.row];
MPMediaItem *cellItem = [collection representativeItem];
其中_items
是一个包含MPMediaQuery
的结果的NSArray。
【问题讨论】:
【参考方案1】:对于大型库,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;
它要快得多。在包含 1161 个专辑的 iPhone 6 库上:
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
【讨论】:
请问您能在 Swift 3 中使用上述内容吗?【参考方案2】:您如何通过查询访问相册?有 items 方法,或者,如果我没记错的话,还有 collection 方法。它们在为您提供数据的方式上有所不同。
显然,您可以自己手动完成所有操作,只需获取所有专辑的列表并自行排序!
编辑 I:按专辑艺术家分组意味着该集合为您提供每个专辑艺术家,然后获得代表性项目基本上只是一张专辑。因此,您需要再次查询该收藏以获取该艺术家的每张专辑
编辑 II:您可以使用您已经找到的内容来执行其他查询,例如,您已经获得的是所有不同专辑艺术家的集合。您想知道每个艺术家的专辑是什么,以便您可以使用附加谓词重复查询:
MPMediaItem* 专辑艺术家; // 之前的来源 MPMediaQuery* albumQuery = [MPMediaQuery albumsQuery]; MPMediaPropertyPredicate* albumPredicate = [MPMediaPropertyPredicate predicateWithValue: [albumArtist valueForProperty: MPMediaItemPropertyAlbumArtist] forProperty: MPMediaItemPropertyAlbumArtist]; [albumQuery addFilterPredicate: albumPredicate]; NSArray* allAlbums = [albumQuery 集合];
【讨论】:
我已编辑原始问题以解释我如何访问查询。至于手工操作——我已经考虑过了,但我更喜欢使用 MPMediaQuery 拥有的漂亮访问器。 你是什么意思,“对集合进行另一个查询”?能给我举个例子吗? (而且我认为你建议的“手工”方法正在成为越来越有吸引力的选择......) 添加了另一个编辑。 “手动”选项还不错,因为它可以让您更好地控制排序的实际完成方式,因此您可以说您想按艺术家、专辑、歌曲标题(或在专辑),而我不知道内置排序会做什么,可能类似! 谢谢,成功了!主要问题是 MPMedia 项目操作在一个相当大的库上很慢。我添加了我的解决方案作为未来参考的答案。我没有将其标记为解决方案,因为它仍然可以改进。 有趣,我还没来得及检查性能,有趣的是看看它与更“手动”的方法相比如何【参考方案3】:以下作品(慢慢地,在相当大的音乐库中。您的结果可能会有所不同)。感谢 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;
【讨论】:
以上是关于使用 MPMediaQuery 按艺术家对专辑进行排序的主要内容,如果未能解决你的问题,请参考以下文章
快速使用 MPMediaQuery 获取索引 uitableview 的专辑标题?