AVAudioPlayer无法播放声音。

4
我有一个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个回答

3

在声音播放之前,您的“mySounds”作用域已经过期。将其设置为实例变量,看看会发生什么。


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

它运行得非常好。


奇怪。这对我也不起作用。但如果它确实起作用的话,问题似乎是它不一定会在WatchKit发送消息时触发播放声音,而是会在WatchKit会话启动时播放声音。 - Darrell Brogdon

1
WatchConnectivity方法在应用程序生命周期的早期被调用。建议您在AppDelegate或ExtensionDelegate中设置它们。否则,这些方法将在委托设置之前被调用,您可能会错过它们。
在iOS中,应该在application:didFinishLaunchingWithOptions中调用。在watchOS中,应该在ExtensionDelegate的init方法中调用。之所以在手表扩展中的init方法中进行设置,是因为如果您启动了一个复杂的应用程序,则不会调用applicationDidFinishLaunching方法,但是对于复杂应用程序和手表扩展,都会调用init方法。
如果您需要向UIViewController发送数据,可以使用NSNotificationCenter通知控制器。此外,请记住,watch connectivity方法都在后台线程上调用,以防您尝试更新任何UI。

我尝试了这个,但仍然不起作用。似乎与在ChildClass中播放音频有关。如果我将音频代码移回到session:didReceiveMessage:replyHandler:中,它就可以工作了。 - Darrell Brogdon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接