開発メモ

開発関係のメモをいろいろと。たぶん。

プレイリストを自分で作成

動作を確認した環境

環境 情報
Xcode 6.3.2 (6D2105)
iOS 8.3
Swift 1.2
Date 2015/6/6

プレイリストを自分で作成

プレイリストを画面に表示したいんだけど、setQueueWithQuery()で再生キューを設定した場合は中身を調べるのが面倒。というわけで、自分でプレイリストを作成して、再生キューにセットするように修正する。

基本的な流れはこんな感じ。

  1. アプリの目的に合わせてプレイリストを作成
  2. MPMusicPlayerControllerの管理クラスでプレイリストを保存
  3. プレイリストをMPMusicPlayerControllerの再生キューに登録

もちろん、プレイリスト作成の処理を呼び出すように、他の部分も多少修正が必要。

1. アプリの目的に合わせてプレイリストを作成

今回は、再生回数が少ない順に100曲を取り出すようにしてみた。

class MusicPlayerAdmin: SK4MusicPlayerAdmin {

    /// プレイリストを更新
    func updatePlaylist() {
        let query = MPMediaQuery.songsQuery()
        if var all_ar = query.items as? [MPMediaItem] {

            // 再生回数と曲名でソート
            all_ar.sort() { s0, s1 in
                if s0.playCount == s1.playCount {

                    // FIXME: 間違ってはいないが正しくもない

                    return s0.title < s1.title

                } else {
                    return s0.playCount < s1.playCount
                }
            }

            // 最大で100件取り出し
            let no = min(100, all_ar.count)
            playlist = [MPMediaItem](all_ar[0..<no])
        }
    }

    ※関係ない部分は省略

}

やってることは単純で、すべての曲を再生回数&曲名でソートして、最大で100件を取り出してるだけ。本当ならNSPredicateを使うべきなんだろうけど、手抜きで全て自分で処理。

処理自体はどこにおいても問題ないんだけど、今回はこのアプリに特化した管理クラスにおいてある。つまり、最後の代入で使ってるplaylistが、管理クラス(この場合は基底クラス)でプレイリストを保存する変数って事。

2. MPMusicPlayerControllerの管理クラスでプレイリストを保存

プレイリストを保存する部分はこんな感じにしてみた。

class SK4MusicPlayerAdmin: NSObject {

    /// アプリで作成したプレイリスト
    var playlist = [MPMediaItem]() {
        didSet {
            playlistToQueue()
        }
    }

    /// プレイリストを再生キューにセット
    func playlistToQueue() {
        if playlist.isEmpty == false {
            let col = MPMediaItemCollection(items: playlist)
            player.setQueueWithItemCollection(col)
        } else {

            // プレイリストが空の場合、停止にしておく
            stop()
        }
    }

    ※関係ない部分は省略

}

単純に、MPMediaItemの配列に保存しているだけ。データが変更されたら、playlistToQueue()を呼び出して再生キューを更新している。

3. プレイリストをMPMusicPlayerControllerの再生キューに登録

今のところ、保存しているプレイリストが変更されたら、自動的にMPMusicPlayerControllerの再生キューに反映するようにしてある。・・・けど、この実装のままでいいかは微妙。内部のプレイリスト更新と、再生キューへの登録は別々にしたほうが便利なこともあるかも?

プレイリストが空の時の処理も微妙。そもそも、空のプレイリストをセットしたら実行時エラーって仕様がおかしいのでは・・・

ソースコード

最終的なソースコードはこちら。

See_Ku / MusicPlayerTips — Bitbucket
https://bitbucket.org/See_Ku/musicplayertips

https://itunes.apple.com/jp/app/four-album-shuffle-arubamu/id866046150?mt=8&uo=4&at=10l8JW&ct=hatenablog