Więc nie widziałem interfejsu publicznego, aby uzyskać adres URL z obiektu NSSound
, więc poszedłem przebić się przez private headers, aby zobaczyć, co mogłem znaleźć. Okazuje się, że istnieją prywatne metody instancji url
i _url
, które zwracają adres URL NSSound
. Prawdopodobnie są to moduły pobierające dla ivar lub własności.
Z Objective-C byłoby to łatwe: wystarczyłoby dodać metody do nowego interfejsu lub rozszerzenia. Z czystymi Swift rzeczy są trochę trudniejsze, a my musimy narażać akcesor za pośrednictwem protokołu Objective-C:
@objc protocol NSSoundPrivate {
var url: NSURL? { get }
}
Od url
jest metoda instancji, można uzyskać lepsze wyniki z func url() -> NSURL?
zamiast używać zmiennej. Twój przebieg może się różnić: używanie var
do emulowania zachowania właściwości tylko do odczytu wydaje się działać dla mnie.
pisałem nową ogólnospożywczy inicjator jej przedłużenia na 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
}
}
}
Zastosowanie:
let url = NSURL(...)
if let sound = NSSound(contentsOfURL: url, byReference: true) {
do {
let player = try AVAudioPlayer(sound: sound)
player?.play()
} catch {
print(error)
}
}
Po próbując znaleźć coś związanego NSData
w Ivars, metody instancji i właściwości NSSound, doszedłem do wniosku, że część danych jakiejkolwiek używasz do zainicjowania NSSound
jest zaciemniana gdzieś w implementacji klasy i nie jest dostępna tak jak URL to.
Jeśli plik audio nie istnieje, czy ta linia nie zawiesi się? 'aSound.sound = NSSound (contentsOfURL: aSound.path)!' – brimstone
Tak, ale w tym przypadku '.sound' nigdy nie jest puste. – Matt
Szczerze mówiąc, nie sądzę, że można uzyskać dane dźwiękowe z NSSound. – brimstone