Swift 4 переключиться на новый API наблюдения

У меня проблемы с новым observe API в Swift 4.

player = AVPlayer()
player?.observe(\.currentItem.status, options: [.new], changeHandler: { [weak self] (player, newValue) in
    if let status = AVPlayer.Status(rawValue: (newValue as! NSNumber).intValue) {

   }
 }

Но я получаю ошибку

Тип выражения неоднозначен без дополнительного контекста.

Как мне это исправить? Не уверен насчет keyPath синтаксис.

Существует также предупреждение при извлечении AVPlayerStatus в закрытии выше

Преобразование из 'NSKeyValueObservedChange' в несвязанный тип 'NSNumber' всегда завершается неудачей "

2 ответа

Решение

currentItem является необязательным свойством AVPlayer, Следующие компиляции в Swift 4.2/Xcode 10 (обратите внимание на дополнительный вопросительный знак в ключевом пути):

let observer = player.observe(\.currentItem?.status, options: [.new]) {
    (player, change) in
    guard let optStatus = change.newValue else {
        return // No new value provided by observer
    }
    if let status = optStatus {
        // `status` is the new status, type is `AVPlayerItem.Status`
    } else {
        // New status is `nil`
    }
}

Наблюдаемое свойство является необязательным AVPlayer.Status?, следовательно change.newValue внутри обратного вызова есть "двойной необязательный" AVPlayer.Status?? и должен быть развернут дважды.

Он может не скомпилироваться в более старых версиях Swift. Сравните Swift 'наблюдаем ()', не работает для ключевых путей с опциями? в форуме Swift.

Вы также можете использовать экземпляр проигрывателя вместо изменения (NSKeyValueObservedChange) из закрытия, чтобы получить то, что вам нужно.

      

//Declare observation token at class level for managing the observation lifetime.

    var kvoToken: NSKeyValueObservation?

//Add your observer

    kvoToken = player.observe(\.currentItem?.status) { (player, _) in
                switch player.currentItem?.status {
                case.readyToPlay:
                    print("Ready to play")
                case .failed:
                    print("failed")
                case .unknown:
                    print("unknown")
                default:
                    print("deafult")
                }
            }

//In deinit, invalidate the token.

    deinit {
        kvoToken?.invalidate()
    }
Другие вопросы по тегам