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()
}