5

This is the first time I use SKAudioNode. First I declared a property at the top of my GameScene class:

var backgroundMusic: SKAudioNode!

Now I added a helper method:

func playBackgroundMusic(name: String) {
    if backgroundMusic != nil {
        backgroundMusic.removeFromParent()
    }

    backgroundMusic = SKAudioNode(fileNamed: name)
    backgroundMusic.autoplayLooped = true
    addChild(backgroundMusic)
}

Now I called this method like this:

playBackgroundMusic("ABC.caf")

It throws an fatal error on this line:

backgroundMusic.autoplayLooped = true

Saying: unexpected found nil while unwrapping optional value.

I did make sure the following

  • ABC.caf is in my project and is listed in the copy bundle resources.
  • It is spelled correctly.

Now where else should I check for errors?

EDIT:

Here are my configuration info:

  • Xcode 7.3
  • iPhone with iOS 9.3.2
  • Simulator with iOS 9.3

Both the device and the simulator doesn't work.

EDIT2:

I changed my codes to the following:

func playBackgroundMusic(name: String) {
    if backgroundMusic != nil {
        backgroundMusic.removeFromParent()
    }

    let temp = SKAudioNode(fileNamed: name)
    temp.autoplayLooped = true
    backgroundMusic = temp
    //backgroundMusic = SKAudioNode(fileNamed: "SpaceGame.caf")
    //backgroundMusic.autoplayLooped = true
    addChild(backgroundMusic)
}

Now my app doesn't crash anymore but it has no sounds. Any ideas?

P.S. Few minute after I last edited that question I tried replacing everything in that method with:

runAction(SKAction.playSoundFileNamed(name, waitForCompletion: false))

Still no sound. Perhaps a problem with the sound file?

Tom Shen
  • 1,328
  • 2
  • 11
  • 35
  • You are on Xcode 7.3 right ? http://stackoverflow.com/q/36273271/3402095 For me, when using Xcode 7.1.1 even if I provide wrong filename, `backgroundMusic` will not end up as nil, but rather with some kind of an "empty" SKAudioNode. Still, it will not crash. By the way, have you tried to re-add the sound? You know, delete it from project, then go Product-> clean, then drag the same sound again to the project and add it to Copy Bundle Resources section... Just to see if this is not related to some weird caching issue (but I doubt that). – Whirlwind Apr 09 '16 at 15:45
  • @Whirlwind Yes, I am on Xcode 7.3. I tried to delete the music file and re-add it back to the project, and performed a clean. Still it crashes because it found nil while unwrapping an optional. – Tom Shen Apr 09 '16 at 15:58
  • Did you try with just "ABC" instead of "ABC.caf"? – Good Doug Apr 10 '16 at 05:59
  • @GoodDoug I tried it, same error. – Tom Shen Apr 10 '16 at 11:17
  • did you check to make sure the file is included in your build? Just adding to the project may not be good enough. Also, the filename is case sensitive, did you name the file SpaceGame.caf and not spaceGame.caf – Knight0fDragon Apr 10 '16 at 14:44
  • @Knight0fDragon I did make sure the file is spelled correctly and the case are correct. And the file is also in my project and in the app bundle. – Tom Shen Apr 10 '16 at 15:24

4 Answers4

13

I just ran into this issue. Apparently, it only works with local variables now. The below code worked.

var background:SKAudioNode!

override func didMoveToView(view: SKView) {
    let bg = SKAudioNode(fileNamed: "bg.mp3")
    addChild(bg)
    background = bg
}
Ryan A.
  • 131
  • 2
1

I fixed this problem with the code I put in EDIT2 above:

func playBackgroundMusic(name: String) {
    if backgroundMusic != nil {
        backgroundMusic.removeFromParent()
    }

    let temp = SKAudioNode(fileNamed: name)
    temp.autoplayLooped = true
    backgroundMusic = temp
    //backgroundMusic = SKAudioNode(fileNamed: "SpaceGame.caf")
    //backgroundMusic.autoplayLooped = true
    //addChild(backgroundMusic)
    runAction(SKAction.playSoundFileNamed(name, waitForCompletion: false))
}

For the no sound part just make sure the side switch on your iPhone is not on red.

Tom Shen
  • 1,328
  • 2
  • 11
  • 35
  • This deserves a face palm, now that you have it working, try taking out the temp and see if it works again. I know SKAudioNode has an issue with the headphone jack, perhaps there is an issue with the switch as well. – Knight0fDragon Apr 11 '16 at 16:23
1

I was having a similar issue with SKAudioNode(fileNamed:) and it looked from the autocomplete and from the problems I was having like there are two distinct initializers with the same parameter signature, one returning SKAudioNode and one returning SKNode and I was somehow getting the wrong one. I switched to using SKAudioNode(url:) instead (getting the URL using Bundle.main.url(forResource:withExtension:)) and everything worked as expected.

Isaac
  • 9,841
  • 5
  • 57
  • 62
1

It's been some years, but this I found out that constructor SKAudioNode() takes some time to load the sound - no matter how big it is. Even a small sound file of 50 kByte take 0.25 seconds to load. After the initial use all subsequent loadings of the sound take only a fraction of that time. I am guessing that SpriteKit does some caching with all sounds in the app file.

So to solve the problem of the first delayed sound: Play them like I the menu - with zero volume and zero length.

My experiments show - pre-playing like 20 sound files also takes 0.25 seconds I the Xcode 11 simulator to initialise. So I am guessing again that pre-playing one(!) sound tells iOS to pre-loading all sound files into memory.

NeoLeon
  • 33
  • 5