2016-04-27 31 views
11

AVAudioPlayer örneklerine dönüştürmek istediğim NSSound nesnem var. Ben NSSound nesneleri ile ilişkili dosya yollarını (NSURL s) var, ancak özgün dosya mevcut olmayabilir.NSSound'u AVAudioPlayer'a Dönüştürme

class SoundObj: NSObject { 
    var path: NSURL? 
    var sound: NSSound? 
    var player: AVAudioPlayer 
} 

let aSound = SoundObj() 
aSound.path = NSURL(fileURLWithPath: "file:///path/to/sound.m4a") 
aSound.sound = NSSound(contentsOfURL: aSound.path)! 

do { 
    try aSound.player = AVAudioPlayer(contentsOfURL: aSound.path) 
} catch { 
    // perhaps use AVAudioPlayer(data: ...)? 
} 

Nasıl bir AVAudioPlayer örneğine bir NSSound nesneyi dönüştürebilirim: İşte ben bugüne kadar ne var?

+0

Ses dosyası yoksa, bu satır çökmez mi? 'aSound.sound = NSSound (contentOfURL: aSound.path)!' – brimstone

+0

Evet, ama bu durumda '.sound' asla boş değil. – Matt

+0

Dürüst olmak gerekirse, bir NSSound'dan ses verisi alabileceğinizi düşünmüyorum. – brimstone

cevap

2

URL'yi bir NSSound nesnesinden almak için genel bir arabirim görmedim, bu yüzden ne bulabildiğimi görmek için private headers'u incelemeye başladım. Özel bir yöntem url ve _url olduğu için, NSSound URL'sini döndürür. Muhtemelen bunlar bir NSURL ivar veya mülk için alıcılardır.

Objective-C ile bu kolay olurdu: yöntemleri yeni bir arabirime veya uzantıya eklerdik. Saf Swift işler biraz yanıltıcıdır vardır ve biz bir Objective-C protokolü aracılığıyla erişimci maruz gerekir olarak: url yana

@objc protocol NSSoundPrivate { 
    var url: NSURL? { get } 
} 

bir örnek yöntemidir, sen func url() -> NSURL? yerine bir değişken kullanarak daha iyi sonuçlar elde edilebilir. Milajınız değişiklik gösterebilir: bir salt okunur özellik davranışını benim için işe yarayacak gibi görünmek için bir var kullanarak.

Ben AVAudioPlayer üzerinde bir uzantısı yeni bir kolaylık başlatıcı yazdı:

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

Kullanımı:

let url = NSURL(...)  
if let sound = NSSound(contentsOfURL: url, byReference: true) { 
    do { 
     let player = try AVAudioPlayer(sound: sound) 
     player?.play() 
    } catch { 
     print(error) 
    }   
} 

Ivars içinde NSData ile ilgili her şeyi, örneğin yöntemleri ve özelliklerini bulmak denemeden sonra Bir NSSound, bir NSSound'u başlatmak için kullandığınız her şeyin veri kısmının, sınıfın uygulanmasında bir yere gizlendiğini ve şu şekilde mevcut olmadığı sonucuna vardım. URL