2016-01-25 171 views
4

我有一个WatchKit应用程序,当手表上的按钮被点击时,它会通知iOS应用程序播放声音。出于某种原因,当我使用自定义类来处理设置AVAudioPlayer的实例并播放声音时,声音不会播放。如果我在session:didReceiveMessage:replyHandler:之内做到这一点,它会很好。AVAudioPlayer不播放声音

这是自定义类:

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应用可能没有播放音频?

回答

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

它工作得很好。

+0

奇怪。这对我也不起作用。但是如果这样做的话,看起来像是一个问题,那就是当WatchKit发送消息时它不一定会触发播放声音,而是在WatchKit会话启动时播放声音。 –

1

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

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

如果你需要发送数据到UIViewController就像你的情况,你使用NSNotificationCenter来通知控制器。另外,请记住手表连接方法都在后台线程上调用,以防您尝试更新任何UI。

+0

我试过了,它仍然无法工作。看起来好像在'ChildClass'中有音频播放是相关的。如果我将音频代码移回'session:didReceiveMessage:replyHandler:'它可以工作。 –

2

在播放声音之前,您的“mySounds”超出了范围。 将其设为实例变量并查看会发生什么。