AppleMusic連携で曲の固有のIDからMPMediaItemを取得したり曲を再生する時の知見

[Media Player](https://developer.apple.com/documentation/mediaplayer/) のFrameworkを使ってAppleMusic連携のアプリを作りたい。
しかしこんなんドキュメント見ても分からんだろっていう落とし穴があったりするので、いろいろ試してわかった知見を書く。

## 曲固有のID
単一の曲を表す[MPMediaItem](https://developer.apple.com/documentation/mediaplayer/mpmediaitem)にはいろいろとプロパティがあるが、曲を区別するためのIDは次の二つがある。似ているようで役割が違う。

### persistentID
自分のライブラリ内の固有のID(と思われる)
このIDがあれば、[MPMediaItem](https://developer.apple.com/documentation/mediaplayer/mpmediaitem)は取得できる。

次のように、`MPMediaPropertyPredicate`,`MPMediaQuery`を使ってpersistentIDからMPMediaItemを取得する。
`MPMediaItemPropertyPersistentID `というプロパティを使って絞り込もう。

```swift
private func findMPMediaItem(persistentIDString: String) -> MPMediaItem? {
        let predicate = MPMediaPropertyPredicate(value: persistentIDString, forProperty: MPMediaItemPropertyPersistentID)
        let songQuery = MPMediaQuery()
        songQuery.addFilterPredicate(predicate)
        
        if let items = songQuery.items {
            return items.first
        } else {
            return nil
        }
}
```

### playbackStoreID
こちらはApple MusicやiTunes全体で固有のID(と思われる)

[iTuneSearchAPI](https://developer.apple.com/library/archive/documentation/AudioVideo/Conceptual/iTuneSearchAPI/LookupExamples.html)を例にすると、このようにAPIを叩けば曲の情報が取得できる。

```bash
$ curl "https://itunes.apple.com/lookup?id=1513201190" | jq
```

また、[Apple Music API](https://developer.apple.com/documentation/applemusicapi/)でも曲の情報を取得できるが、こちらはtokenが必要だったりするので省略する。


#### ただしこのIDからMPMediaItemは取得できない!!😩
↑わたしが調べる限り2020年8月時点では不可能っぽい。使えるようになったら教えてほしい。🙏

`MPMediaItemPropertyPlaybackStoreID`といういかにも使えそうなプロパティはあるのだが、使うと次のようなエラーで怒られるぞ。[stackoverflow](https://stackoverflow.com/questions/48835337/how-to-get-an-mpmediaitem-from-a-saved-playbackstoreid-i-e-for-apple-music-pla)にある通り、現状は取得する手段がない。

```swift
"MPMediaPropertyPredicate cannot filter using the playbackStoreID property"
```



## 曲を再生したい場合は？

### persistentIDを使う場合



曲を再生する時は[MPMusicPlayerController](https://developer.apple.com/documentation/mediaplayer/mpmusicplayercontroller)のこれをつかう

```swift
 open func setQueue(with itemCollection: MPMediaItemCollection)
```

次のようにMPMediaItemからMPMediaItemCollectionを作って、セットすれば再生できる

```swift
//itemsは↑みたいな方法で取得しとく
let mediaItemCollection = MPMediaItemCollection(items: items)
let musicPlayer: MPMusicPlayerController = MPMusicPlayerController.systemMusicPlayer
musicPlayer.setQueue(with: mediaItemCollection)
```



### playbackStoreIDを使う場合
こちらの場合、MPMediaItemは取得できない

しかし曲の再生はできる。
[MPMusicPlayerController](https://developer.apple.com/documentation/mediaplayer/mpmusicplayercontroller)のこれをつかう

```swift
open func setQueue(with storeIDs: [String])
```

次のように書けばok

```swift
let musicPlayer: MPMusicPlayerController = MPMusicPlayerController.systemMusicPlayer
musicPlayer.setQueue(with: ["1513201190"])
```


## まとめ

`persistentID`は自分のライブラリ固有のIDで、MPMediaItemを取得できる。
`playbackStoreID`はApple MusicやiTunes全体で固有のIDで、API利用して曲の情報を取得できる。

[Apple Music API](https://developer.apple.com/documentation/applemusicapi/)を使ったアプリを作りたい時は`playbackStoreID`を使うと良さそう。
Swiftでネイティブアプリを作りたい時は、`persistentID`と`playbackStoreID`どう使うか考えると良さそう。


## 参考

- https://qiita.com/noppefoxwolf/items/01cba69b910860d34551
- https://qiita.com/hanawat/items/c59c3365156a474821cc