【Objective-C】MPMediaQueryで取得される曲情報にはiCloudも含まれる

【Xcode5.1.1 + iOS 7.1 + MacOX10.9.5】

MPMusicPlayerControllerでミュージックライブラリの再生をしていて、一覧に出てくるのに再生できない曲があって「何だろう?プログラムの問題?」といろいろ調べていたら・・・

MPMediaQueryで取得される曲情報にはiCloudも含まれる

ということらしい。リストにはあるけど、曲データがないので再生できない。というか、[MPMusicPlayerController play] ではエラーにはならずに再生した途端に「MPMusicPlayerControllerPlaybackStateDidChangeNotification」が返ってきて、MPMediaItem == NULL で再生終了になる。

※問題の出たアルバムは1曲しか含まれていなかったので。

具体的には、MPMediaItem に MPMediaItemPropertyIsCloudItem というプロパティがあります。これでiCloudにあるのかどうか判定できます。

・MPMediaItemPropertyIsCloudItem
A Boolean value indicating whether the media item is an iCloud item (YES), or not (NO). A media item is considered an iCloud item if it is available via iTunes Match and is not already stored on the device. Value is an NSNumber object representing a BOOL data type.

Available in iOS 6.0 and later.

・元々のコードはこんな感じ。

MPMediaQuery *query = [MPMediaQuery albumsQuery];

NSArray *albumlists = query.collections;

for (MPMediaItemCollection *albumlist in albumlists) {
MPMediaItem *representativeItem = [albumlist representativeItem];
NSString *albumtTitle = [representativeItem valueForProperty:MPMediaItemPropertyAlbumTitle];
}

・で、調べてみたら、iCloudのデータを除外するには [MPMediaQuery addFilterPredicate:] ですればOK。

MPMediaQuery *query = [MPMediaQuery albumsQuery];

[query addFilterPredicate:[MPMediaPropertyPredicate predicateWithValue:[NSNumber numberWithBool:NO] forProperty:MPMediaItemPropertyIsCloudItem]];

NSArray *albumlists = query.collections;

for (MPMediaItemCollection *albumlist in albumlists) {
MPMediaItem *representativeItem = [albumlist representativeItem];
NSString *albumtTitle = [representativeItem valueForProperty:MPMediaItemPropertyAlbumTitle];
}

問題の出た曲データが特定できなくて、iOS純正のミュージックプレイヤーと自作アプリの曲アルバム一覧を比較していて、やっと気づきました。

【参考】
MPMediaItem Class Reference | iOS Developer Library
MPMediaQuary albumsQuery結果からiCloudのみにあるものを除く | 響雲
articles of samekard: iPod library access クラウド音源への対応
MPMediaQuery – ignore songs on Cloud (i.e., iTunes Match)