開発メモ

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

playbackStateChangedでボタンがちらつく問題に対応

動作を確認した環境

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

playbackStateChangedでボタンがちらつく問題に対応

具体的に説明すると、アプリを起動して最初の再生で、PauseとPlayのボタンがちらつく問題。これは、MPMusicPlayerControllerPlaybackStateDidChangeNotificationが立て続けに複数回送られてくるのが原因。

まったく理由はわからないんだけど、PlayingとPausedが交互に複数回送られてくる。一定の間隔でタイマーを回して、そこでステータスをチェックするような実装であれば、この通知そのものを無視すればいいんだけど、まじめに毎回UIを更新するような実装だとボタンがちらつくことに。

仕方がないので、一定の間隔で立て続けに通知が来た場合、最後の1回だけ実際の処理を行うように修正してみた。

class SK4MusicPlayerAdmin: NSObject {

    /// playbackStateChangedの実行回数
    var stateChangeCount = 0

    func playbackStateChanged(notify: NSNotification) {

        // 通知の直後はAVAudioSessionで再生状況が取れないので、
        // 少し遅らせてチェックする
        let time = dispatch_time(DISPATCH_TIME_NOW, Int64(NSEC_PER_SEC / 10))
        let queue = dispatch_get_main_queue()

        // 今回の実行回数を保存
        let count = ++stateChangeCount

        dispatch_after(time, queue) { [weak self] in

            // このループの実行回数が現在の値と一致した時だけ、処理を実行
            if let tmp = self where tmp.stateChangeCount == count {
                tmp.onPlaybackStateChanged()
            }
        }
    }

    ※関係ない部分は省略
}

やってることは単純で、遅延実行を指定したクロージャが実行される時点で実行回数をチェック。クロージャがつかんでる実行回数と一致した場合(つまり、この処理が最新の場合)だけ、実際に実行するようにしてある。

この手の処理はたまにあると便利なので、本当なら、使いやすい形で仕上げておくべき。

ソースコード

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

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

https://itunes.apple.com/jp/app/cross-sum-100/id981012596?mt=8&uo=4&at=10l8JW&ct=hatenablog