Search code examples
swiftavplayerswift3

AVPlayerItemDidPlayToEndTime never reaches selector on Swift 3


I'm adapting my app to Swift 3 and I'm encountering this problem. This used to work on Swift 2.2 but now it's broken. moviePlayBackFinished never gets called. I tried adding the observer in multiple ways, all without success.

    NotificationCenter.default.addObserver(self, selector: #selector(self.moviePlayBackFinished(_:)),
                                           name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: player.currentItem);

    NotificationCenter.default.addObserver(self, selector: #selector(moviePlayBackFinished(_:)),
                                           name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: player.currentItem);

    NotificationCenter.default.addObserver(self, selector: #selector(self.moviePlayBackFinished(sender:)),
                                           name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: player.currentItem);

// (...)

@objc func moviePlayBackFinished(sender : AnyObject) {
    print("playbackFinished");
    let zeroCM : CMTime = CMTime(seconds: 0, preferredTimescale: 1000000000);
    playerLayer.player?.seek(to: zeroCM);
}

@objc func moviePlayBackFinished(_ notification: Notification) {
    print("playbackFinished");
    let zeroCM : CMTime = CMTime(seconds: 0, preferredTimescale: 1000000000);
    playerLayer.player?.seek(to: zeroCM);
}

Any ideas would be appriciated.

Thank you


Solution

  • There are multiple possible reason of this issue.

    NotificationCenter
        .default
        .addObserver(self, 
                     selector: #selector(self.moviePlayBackFinished(sender:)),
                     name: .AVPlayerItemDidPlayToEndTime,
                     object: player.currentItem)
    

    First of all, you have to set object to nil. AVPlayerItemDidPlayToEndTime notification automatically set object to the AVPlayerItem which reached at the end. If you change it manually, you will not get any notification of AVPlayerItemDidPlayToEndTime.

    Second, according to the AVPlayerItemDidPlayToEndTime documentation:

    Important

    This notification may be posted on a different thread than the one on which the observer was registered.

    So, to make sure you should check the notification is on the thread you want.

    It doens't matter you added observer from UIViewController or AVPlayer subclass.