MPMediaQuerysearch艺术家,专辑和歌曲

如何以与iOS音乐应用程序相同的方式searchiPod库? 我想进行一般查询,返回每个艺术家,专辑和歌曲的结果。 例如,如果我searchKenny Chesney,我希望歌曲查询返回所有Kenny Chesney歌曲(以及任何包含Kenny Chesney的歌曲标题或专辑)。当我为每个属性(歌曲标题,专辑标题,艺术家的名字),一个空数组返回。

下面是一些代码,可以让你更好地了解我正在尝试完成的任务:

MPMediaPropertyPredicate *songPredicate = [MPMediaPropertyPredicate predicateWithValue:searchText forProperty:MPMediaItemPropertyTitle comparisonType:MPMediaPredicateComparisonContains]; MPMediaPropertyPredicate *albumPredicate = [MPMediaPropertyPredicate predicateWithValue:searchText forProperty:MPMediaItemPropertyAlbumTitle comparisonType:MPMediaPredicateComparisonContains]; MPMediaPropertyPredicate *artistPredicate = [MPMediaPropertyPredicate predicateWithValue:searchText forProperty:MPMediaItemPropertyArtist comparisonType:MPMediaPredicateComparisonContains]; MPMediaQuery *songsQuery = [MPMediaQuery songsQuery]; [songsQuery addFilterPredicate:songNamePredicate]; [songsQuery addFilterPredicate:artistNamePredicate]; [songsQuery addFilterPredicate:albumNamePredicate]; NSLog(@"%@", [songsQuery items]); 

我有这个工作,通过与每个谓词分别运行查询,但这似乎是非常低效的!

结合你的谓词这种方式使它像“和”的关系。 这意味着你正在查询一首标题,专辑和名字都与search文字相匹配的歌曲。

为了达到你所要做的,你应该运行3个查询,并以适当的方式结合结果。

如果你运行:

 MPMediaPropertyPredicate *artistPredicate = [MPMediaPropertyPredicate predicateWithValue:searchText forProperty:MPMediaItemPropertyArtist comparisonType:MPMediaPredicateComparisonContains]; NSSet *predicates = [NSSet setWithObjects: artistPredicate, nil]; MPMediaQuery *songsQuery = [[MPMediaQuery alloc] initWithFilterPredicates: predicates]; NSLog(@"%@", [songsQuery items]); 

这将返回与您的search匹配的艺术家。 你应该为歌曲和专辑做同样的事情。

如果你这样做很慢,你可以一次检索所有媒体并手动过滤:

 MPMediaQuery *everything = [[MPMediaQuery alloc] init]; NSLog(@"Logging items from a generic query..."); NSArray *itemsFromGenericQuery = [everything items]; for (MPMediaItem *song in itemsFromGenericQuery) { NSString *songTitle = [song valueForProperty: MPMediaItemPropertyTitle]; /* Filter found songs here manually */ } 

这对我有用:

 MPMediaQuery *searchQuery = [[MPMediaQuery alloc] init]; NSPredicate *test = [NSPredicate predicateWithFormat:@"title contains[cd] %@ OR albumTitle contains[cd] %@ OR artist contains[cd] %@", searchString, searchString, searchString]; NSArray *filteredArray = [[searchQuery items] filteredArrayUsingPredicate:test]; //NSLog(@"%@", [filteredArray valueForKeyPath:@"title"]); for (MPMediaItem *song in filteredArray) { [arrayOfSongItems addObject:song]; } 

我基本上过滤 ,从媒体查询中获取所有项目。 我不认为我的解决scheme比首先过滤查询更好,但绝对比单独search三次更好。 或者多次遍历数组。

这里有两种方法:

  1. 使用多个MPMediaPropertyPredicates获取使用查询的所有内容。 使用这种方法,您将需要执行多个查询并自己汇总结果。 NSSet是你的朋友!

  2. 从图书馆获取一切(或接近它),然后再进行search或过滤。

在较旧的设备或操作系统版本上访问音乐库的速度会非常慢。 以我自己的经验来实现与你所描述的非常相似的东西,我用方法2得到了最好的结果。一旦我有,那么,我只是使用分散/收集方法迭代这些项目的一切(我的需求不允许使用NSPredicate)。 实际上,这比我的方法1要好得多,不过我知道在iOS 6中差距已经有所收敛了。