iOSデバイスのミュージックライブラリにクエリを行い、そのコンテンツのサブセットを返すコードセクションがあります。このコードがプレイリストに対してトリガーされると、MPMediaQueryを作成し、MPMediaPropertyPredicateを使用して一連のフィルターを適用します。まず、私が望むコンテンツのタイプ(音楽)をフィルタリングし、すべてのクラウドコンテンツを削除し、最後にプレイリストを閲覧するときに、そのプレイリストに属するアイテムをフィルタリングします。これはすべてスマートなプレイリストを除いてうまくいきます(そしてそれはいくつかのデバイスでも機能します)。以下はコードです - 私は最初の2つのフィルターの後もまだ項目のかなりのリスト(10107)を持っていますが、最後のフィルターが適用された後、スマートプレイリストのときはクエリが0個に減らされています。私はある種の整数オーバーフローが起こっていると思ったので、 "値"をNSNumberの代わりにNSDecimalNumberに変更しました。完全なプレイリストIDは常に整数であり、決して科学的な表記法ではありませんが、問題。何が起こっているか考えてみませんか?私が見たログでMPMediaQuery addFilterPredicateスマートプレイリストからクエリからすべてのアイテムを削除します
- (MPMediaQuery*) queryFromObjectId:(NSString*)objectId
{
NSLog(@"INSIDE queryFromObjectId %@", objectId);
NSString *s;
MPMediaQuery* rv = [MPMediaQuery new];
NSURL* url = [NSURL URLWithString:objectId];
NSString* type = url.host;
NSLog(@"URL: %@, type: %@", url, type);
NSArray* rootItem = [self.rootDict objectForKey:type];
if (rootItem != nil) {
rv.groupingType = [rootItem[kRootIndexQuery] groupingType];
}
NSDictionary *parameters = [url nvt_queryDictionary];
MPMediaPropertyPredicate* pred;
// Filter proper media types
if (parameters[MPMediaItemPropertyPodcastPersistentID] || rv.groupingType == MPMediaGroupingPodcastTitle) {
NSLog(@"Filtering for Podcast type");
pred = [MPMediaPropertyPredicate predicateWithValue:[NSNumber numberWithInt:MPMediaTypePodcast] forProperty:MPMediaItemPropertyMediaType];
} else {
NSLog(@"Filtering for music/media type");
pred = [MPMediaPropertyPredicate predicateWithValue:[NSNumber numberWithInt:MPMediaTypeMusic] forProperty:MPMediaItemPropertyMediaType];
}
[rv addFilterPredicate:pred];
// Filter iCloud items
if ([UIDevice currentDevice].systemVersion.floatValue >= 6) {
NSLog(@"Filtering iCloud items");
pred = [MPMediaPropertyPredicate predicateWithValue:[NSNumber numberWithBool:NO] forProperty:MPMediaItemPropertyIsCloudItem];
[rv addFilterPredicate:pred];
}
int index = 0;
for (NSString *key in parameters.allKeys) {
NSLog(@"Inside for loop, KEY: %@, index: %d", key, index);
MPMediaPropertyPredicate *pred;
if ([key isEqualToString:MPMediaPlaylistPropertyPersistentID] || [key isEqualToString:MPMediaItemPropertyPodcastPersistentID]) {
NSLog(@"IF inside FOR");
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
formatter.numberStyle = NSNumberFormatterDecimalStyle;
// NSNumber *value = [formatter numberFromString:parameters[key]];
NSDecimalNumber *value = [NSDecimalNumber decimalNumberWithString:parameters[key]];
pred = [MPMediaPropertyPredicate predicateWithValue:value forProperty:key];
}
else {
NSLog(@"ELSE inside FOR");
id value = parameters[key];
pred = [MPMediaPropertyPredicate predicateWithValue:value forProperty:key];
}
s = [NSString stringWithFormat:@"BEFORE FILTER items:%u", rv.items.count];
NSLog(s);
s = [NSString stringWithFormat:@"Predicate: value: %@, key: %@", pred.value, pred.property];
NSLog(s);
[rv addFilterPredicate:pred];
s = [NSString stringWithFormat:@"AFTER FILTER items:%u", rv.items.count];
NSLog(s);
index++;
}
return rv;
}
:
2017-03-21 11:09:26.090316 T[1978:1214332] INSIDE queryFromObjectId //Tracks?playlistPersistentID=9690568479441451477
2017-03-21 11:09:26.090549 T[1978:1214332] URL: //Tracks?playlistPersistentID=9690568479441451477, type: Tracks
2017-03-21 11:09:26.090690 T[1978:1214332] Filtering for music/media type
2017-03-21 11:09:26.090846 T[1978:1214332] Filtering iCloud items
2017-03-21 11:09:26.090967 T[1978:1214332] Inside for loop, KEY: playlistPersistentID, index: 0
2017-03-21 11:09:26.091017 T[1978:1214332] IF inside FOR
2017-03-21 11:09:26.091200 T[1978:1214332] BEFORE FILTER items:10107
2017-03-21 11:09:26.091298 T[1978:1214332] Predicate: value: 9690568479441451477, key: playlistPersistentID
2017-03-21 11:09:26.091765 T[1978:1214332] AFTER FILTER items:0
このすべては、非スマートプレイリストのために完璧に動作します。
また、何もしていないように見えるiCloudフィルタリング部分を削除した場合、すべてのスマートプレイリストがロードされますが、同じコンテンツを読み込みます。スマートプレイリストのID番号が最も小さいコンテンツ。ここで私がテストしていたプレイリストの名前とIDをされています
は "9690568479441451477"
をTop500MostPlayed "9690568479441451478"
をRecentlyPlayed "9690568479441451479"
5stars "9690568479441451476"
をRecentlyAddediCloudフィルタリングが削除されると、すべてのスマートプレイリストがプレイリスト "5スターズ"のコンテンツを読み込みます。