Ответ 1
Итак, я не видел публичный интерфейс, чтобы получить URL-адрес от объекта NSSound
, поэтому я перешел через частные заголовки чтобы увидеть, что я могу найти. Оказывается, есть частный метод экземпляра url
и _url
, который возвращает URL-адрес NSSound
. Предположительно, это геттеры для NSURL
ivar или свойства.
С Objective-C это будет легко: мы просто добавим методы в новый интерфейс или расширение. С чистыми Swift вещи немного сложнее, и нам нужно разоблачить аксессуар через протокол Objective-C:
@objc protocol NSSoundPrivate {
var url: NSURL? { get }
}
Так как url
- это метод экземпляра, вы можете получить лучшие результаты с помощью func url() -> NSURL?
вместо использования переменной. Ваше возражение может отличаться: использование var
для подражания поведению свойства только для чтения показалось мне полезным.
Я написал новый инициализатор удобства в расширении на AVAudioPlayer
:
extension AVAudioPlayer {
convenience init?(sound: NSSound) throws {
let privateSound = unsafeBitCast(sound, NSSoundPrivate.self)
guard let url = privateSound.url else { return nil }
do {
try self.init(contentsOfURL: url)
} catch {
throw error
}
}
}
Использование:
let url = NSURL(...)
if let sound = NSSound(contentsOfURL: url, byReference: true) {
do {
let player = try AVAudioPlayer(sound: sound)
player?.play()
} catch {
print(error)
}
}
После попытки найти что-либо, связанное с NSData
в ivars, методах экземпляра и свойствах NSSound, я пришел к выводу, что часть данных, которую вы используете для инициализации NSSound
, запутывается где-то в реализация класса и недоступна, например, URL.