4

I tried doing this:

let soundFilePath = NSBundle.mainBundle().pathForResource("GL006_SNES_Victory_loop.aif", ofType: "GL006_SNES_Victory_loop.aif")
let soundFileURL = NSURL(fileURLWithPath: soundFilePath!)
let player = AVAudioPlayer(contentsOfURL: soundFileURL, fileTypeHint: nil)
player.numberOfLoops = -1 //infinite
player.play()

I put this code in the didMoveToView function, and I have import AVFoundation at the top of my code. I get the error: Call can throw, but it is not marked with 'try' and the error is not handled.

Thank you in advance!

Unheilig
  • 16,196
  • 193
  • 68
  • 98
Raxzon
  • 151
  • 1
  • 14

2 Answers2

7

(Xcode 8 and Swift 3)

Using SpriteKit this is pretty simple. You create an SKAudioNote with a sound file and then you attach it to your Scene as a child. It will loop by default:

override func didMove(to view: SKView) {
    let backgroundSound = SKAudioNode(fileNamed: "bg.mp3")
    self.addChild(backgroundSound)
}

If you want to stop the background music at some point you can use the build in methods:

    backgroundSound.run(SKAction.stop())

Or maybe you want to play the sound again after stopping it:

    backgroundSound.run(SKAction.play())

SpriteKit makes this really simple. I hope this helps you.

Alexander Luna
  • 5,261
  • 4
  • 30
  • 36
2

In Swift 2, the parameter of type NSErrorPointer is left out and can be caught within catch block as follows:

do 
{
    let player = try AVAudioPlayer(contentsOfURL: soundFileURL, fileTypeHint: nil)
} 
catch let error as NSError
{
    print(error.description)
}

Addendum:

It is better to declare your AVAudioPlayer as an ivar; otherwise, it could be released and thus the music won't play:

class yourViewController: UIViewController 
{
    var player : AVAudioPlayer!

....

So, given that, we make a minor change to the aforementioned try-catch:

do 
{
    player = try AVAudioPlayer(contentsOfURL: soundFileURL, fileTypeHint: nil)
} 
catch let error as NSError
{
    print(error.description)
}

Edit:

What you originally have:

let soundFilePath = NSBundle.mainBundle().pathForResource("GL006_SNES_Victory_loop.aif", ofType: "GL006_SNES_Victory_loop.aif")
let soundFileURL = NSURL(fileURLWithPath: soundFilePath!)
let player = AVAudioPlayer(contentsOfURL: soundFileURL, fileTypeHint: nil)
player.numberOfLoops = -1 //infinite
player.play()

Hereby adding the catch clause in Swift 2:

let soundFilePath = NSBundle.mainBundle().pathForResource("GL006_SNES_Victory_loop.aif", ofType: "GL006_SNES_Victory_loop.aif")
let soundFileURL = NSURL(fileURLWithPath: soundFilePath!)
do 
{
    player = try AVAudioPlayer(contentsOfURL: soundFileURL, fileTypeHint: nil)
} 
catch let error as NSError
{
    print(error.description)
}
player.numberOfLoops = -1 //infinite
player.play()

Assuming your class is a subclass of SKScene:

class yourGameScene: SKScene
{
    //declare your AVAudioPlayer ivar
    var player : AVAudioPlayer!

    //Here is your didMoveToView function
    override func didMoveToView(view: SKView)
    {
         let soundFilePath = NSBundle.mainBundle().pathForResource("GL006_SNES_Victory_loop.aif", ofType: "GL006_SNES_Victory_loop.aif")
         let soundFileURL = NSURL(fileURLWithPath: soundFilePath!)
         do 
         {
             player = try AVAudioPlayer(contentsOfURL: soundFileURL, fileTypeHint: nil)
         } 
         catch let error as NSError
         {
             print(error.description)
         }
         player.numberOfLoops = -1 //infinite
         player.play()

         //The rest of your other codes
    }
}
Unheilig
  • 16,196
  • 193
  • 68
  • 98
  • Where do i put the class and try-catch? – Raxzon Aug 10 '15 at 01:25
  • Hmmm... now I'm getting this error: `fatal error: unexpectedly found nil while unwrapping an Optional value (lldb)` saying that `soundFilePath!` is `nil`. – Raxzon Aug 10 '15 at 01:53