11

iOS Music アプリケーションと同じ方法で iPod ライブラリを検索するにはどうすればよいですか? アーティスト、アルバム、曲ごとに結果を返す一般的なクエリを作成したいと考えています。たとえば、Kenny 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]);

各述語で個別にクエリを実行することでこれが機能していますが、これは非常に非効率的です!

4

4 に答える 4

16

このように述語を組み合わせると、「AND」関係のようになります。これは、タイトル、アルバム、名前のすべてが検索テキストに一致する曲をクエリしていることを意味します。

やろうとしていることを達成するには、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]);

これにより、検索に一致するアーティストが返されます。曲やアルバムについても同じことを行う必要があります。

これが遅い場合は、すべてのメディアを一度に取得して、手動でフィルタリングできます。

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 */
}
于 2013-02-06T12:31:54.610 に答える
11

これは私のために働きます:

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];
}

基本的に、メディアクエリからすべてのアイテムを取得した後にフィルタリングします。私の解決策は、最初にクエリをフィルタリングするよりも優れているとは思いませんが、3回別々に検索するよりも間違いなく優れています。または、アレイを複数回繰り返します。

于 2013-02-06T15:26:21.337 に答える
2

ここには 2 つのアプローチがあります。

  1. 複数の MPMediaPropertyPredicates を使用して、クエリを使用してすべてを取得します。このアプローチを使用すると、複数のクエリを実行し、結果を自分で集計する必要があります。NSSet はあなたの友達です!

  2. ライブラリからすべて (またはそれに近いもの) を取得してから、検索またはフィルター処理を行います。

古いデバイスや OS のバージョンでは、音楽ライブラリへのアクセスが非常に遅くなることがあります。あなたが説明しているものと非常によく似たものを実装した私自身の経験では、アプローチ 2 で最良の結果が得られました。これには NSPredicate を使用します)。iOS 6 ではその差がいくらか縮まっていることはわかっていますが、これは実際にはアプローチ 1 よりもはるかにパフォーマンスが優れていました。

于 2013-02-13T05:34:25.617 に答える