Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to properly set up the MPNowPlayingInfoCenter in Swift 3

Tags:

ios

swift

spotify

(tl;dr at the bottom)

Currently I'm setting up the properties by:

let mpic = MPNowPlayingInfoCenter.default()
func setInfoCenterCredentials(_ postion: NSNumber, _ duration: NSNumber, _ playbackState: Int) {

    let mySize = CGSize(width: 400, height: 400)
    let albumArt = MPMediaItemArtwork(boundsSize:mySize) { sz in
        return getCoverImage()
    }
    mpic.nowPlayingInfo = [MPMediaItemPropertyTitle: globalTrackName,
                           MPMediaItemPropertyArtist: globalArtistName,
                           MPMediaItemPropertyArtwork: albumArt,
                           MPNowPlayingInfoPropertyElapsedPlaybackTime: postion,
                           MPMediaItemPropertyPlaybackDuration: duration,
                           MPNowPlayingInfoPropertyPlaybackRate: playbackState]
}

Used with the Spotify iOS SDK:

func audioStreaming(_ audioStreaming: SPTAudioStreamingController, didChangePosition position: TimeInterval) {
    if self.isChangingProgress {
        return
    }
    let position = Float(positionDouble / durationDouble)
    let duration = Float((sptAudioStreamCtr?.metadata.currentTrack!.duration)!)    
    globalPositionNumber = NSNumber(value: position)
    globalDurationNumber = NSNumber(value: duration)

    setInfoCenterCredentials(globalPositionNumber, globalDurationNumber, 1)
}

This works pretty well so far.

Problem #1

When I'm hitting the pause button:

enter image description here

The music stops, but the time keeps counting down. I have printed out globalPositionNumber and globalDurationNumber on their didSet and they aren't getting changed. As expected.

Then I have implemented:

func audioStreaming(_ audioStreaming: SPTAudioStreamingController, didChangePlaybackStatus isPlaying: Bool) {

    if !isPlaying {
        setInfoCenterCredentials(globalPositionNumber, globalDurationNumber, 0)
    }
}

Problem now. Hitting pause, results in the timer being reset and starting from 0, once resumed.

Problem #2

enter image description here enter image description here

If I'm swiping up the control panel from within the App, the counters are synced. If I'm leaving the app with the home button and swipe up the control panel from the home screen, the counter starts counting from zero.

Problem #3

If I'm hittin the pause/forward/back buttons from the home screen, they are working well. If I'm swiping up the control panel with my app active and am hitting the buttons, nothing happens.

What am I missing? Help is very appreciated

tl;dr

Problem 1: Time couter of control panel resetted using MPNowPlayingInfoPropertyPlaybackRate 1 or not stopping if not set.

Problem 2: Time counter starts on zero if left the App during the track.

Problem 3: Hitting the action buttons on the control panel with the app active has no effect.

Edit:

override var canBecomeFirstResponder : Bool {
    return true
}

override func remoteControlReceived(with event: UIEvent?) {

    if let ctr = SPTAudioHandler.shared.audioCtrl {
        let rc = event!.subtype
        switch rc {
        case .remoteControlTogglePlayPause:
            ctr.setIsPlaying(!ctr.playbackState.isPlaying, callback: nil)
        case .remoteControlPlay:
            ctr.setIsPlaying(!ctr.playbackState.isPlaying, callback: nil)
        case .remoteControlPause:
            ctr.setIsPlaying(!ctr.playbackState.isPlaying, callback: nil)
        case .remoteControlNextTrack:
            globalBackForthInt = 1
            getNextSpotifyTrack(SPTAudioHandler.shared.spotifyTracks, SPTAudioHandler.shared.playerView)
            globalTrackIndexPath = globalTrackIndexPath + 1
        case .remoteControlPreviousTrack:
            getNextSpotifyTrack(SPTAudioHandler.shared.spotifyTracks, SPTAudioHandler.shared.playerView)
            globalBackForthInt = -1
            getNextSpotifyTrack(SPTAudioHandler.shared.spotifyTracks, SPTAudioHandler.shared.playerView)
            globalTrackIndexPath = globalTrackIndexPath - 1
        default:
            break
        }
    }
}

Everything else is set in setInfoCenterCredentials

like image 847
David Seek Avatar asked Nov 25 '16 12:11

David Seek


2 Answers

The answer was even more simple...

It was a matter of the simulator... All the bugs appeared on a simulator only. Everything works fine on an actual device.

like image 175
David Seek Avatar answered Oct 03 '22 00:10

David Seek


I would suggest re-importing the framework to ensure there are no issues with integration.

As there are no negative reports on GitHub and the code seems fine, it may simply be an integration issue.

Hope this helps :)

like image 23
GJZ Avatar answered Oct 03 '22 00:10

GJZ