AVAudioPlayer没有播放声音

时间:2016-01-25 05:15:01

标签: ios swift2 xcode7 watchkit

我有一个WatchKit应用程序,当手表上点击一个按钮时,它会向iOS应用程序发出声音。出于某种原因,当我使用自定义类来处理设置AVAudioPlayer的实例并播放声音时,声音不会播放。如果我在session:didReceiveMessage:replyHandler:中执行此操作,则播放正常。

这是自定义类:

import AVFoundation

class ChildClass {
    let mySound = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("test", ofType: "wav")!)
    var audioPlayer: AVAudioPlayer!

    func playSound() {
        do {
            print("Playing sound")
            self.audioPlayer = try AVAudioPlayer(contentsOfURL: mySound)
            self.audioPlayer.play()
        } catch {
            print("Error getting audio file")
        }
    }
}

在我的ViewController中实例化:

class ViewController: UIViewController, WCSessionDelegate {
    var session: WCSession!

    override func viewDidLoad() {
        super.viewDidLoad()

        if WCSession.isSupported() {
            session = WCSession.defaultSession()
            session.delegate = self
            session.activateSession()
        }
    }

    func session(session: WCSession, didReceiveMessage message: [String : AnyObject], replyHandler: ([String : AnyObject]) -> Void) {
        let mySounds = ChildClass()
        mySounds.playSound()
    }
}

ChildClass.playSound()中设置断点我可以确认它已被调用。但不仅声音没有播放,而且print()似乎也没有向控制台打印任何内容。

AVAudioPlayer实例是否在自定义类中导致其无法播放声音?或者,由于某种原因,iOS应用程序可能没有播放音频?

3 个答案:

答案 0 :(得分:2)

在声音播放之前,你的“mySounds”超出了范围。 使它成为一个实例变量,看看会发生什么。

答案 1 :(得分:1)

func session(session: WCSession, didReceiveMessage message: [String : AnyObject], replyHandler: ([String : AnyObject]) -> Void) {
    let mySounds = ChildClass()
    mySounds.playSound()
}

未被调用。我尝试将代码放在

if WCSession.isSupported() {
        session = WCSession.defaultSession()
        session.delegate = self
        session.activateSession()

        let mySounds = ChildClass()
        mySounds.playSound()
    }

它运作得很好。

答案 2 :(得分:1)

WatchConnectivity方法在应用程序生命周期的早期调用。建议您在AppDelegate或ExtensionDelegate中进行设置。否则,在设置委托之前将调用这些方法,您可能会错过它们。

在iOS中,应该在应用程序中调用它:didFinishLaunchingWithOptions。在watchOS中,这应该在您的ExtensionDelegate的init方法中。它在watch扩展中的init方法中的原因是因为如果启动复杂化,则不会调用applicationDidFinishLaunching方法,但会为复杂化和监视扩展调用init方法。

如果您需要像您的情况一样将数据发送到UIViewController,您可以使用NSNotificationCenter通知控制器。此外,请记住,如果您尝试更新任何UI,则会在后台线程上调用监视连接方法。