I'm working on a old Swift tutorial (Swift 2.0) that's posted on Ray Wenderlich's web site (https://www.raywenderlich.com/2185-how-to-make-a-letter-word-game-with-uikit-and-swift-part-3-3) and I'm running into an error when I tried to re-setup a function called "preloadAudioEffects" in Swift 4.2 . The error? appendingPathComponent' is unavailable: Use appendingPathComponent on URL instead.

I've tried to rename the old Swift code [Ex: NSBundle to Bundle , stringByAppendingPathComponent to appendingPathComponent()], but I'm still running into some syntax issues due to my inexperience with Swift.

This is the original code:

func preloadAudioEffects(effectFileNames:[String]) {
  for effect in AudioEffectFiles {
    //1 get the file path URL
    let soundPath = NSBundle.mainBundle().resourcePath!.stringByAppendingPathComponent(effect)
    let soundURL = NSURL.fileURLWithPath(soundPath)

    //2 load the file contents
    var loadError:NSError?
    let player = AVAudioPlayer(contentsOfURL: soundURL, error: &loadError)
    assert(loadError == nil, "Load sound failed")

    //3 prepare the play
    player.numberOfLoops = 0
    player.prepareToPlay()

    //4 add to the audio dictionary
    audio[effect] = player
  }
}

And this is what I've tried to do via following the suggestions in Xcode:

func preloadAudioEffects(effectFileNames:[String]) {
        for effect in AudioEffectFiles {
            //1 get the file path URL
            let soundPath = Bundle.main.resourcePath!.appendingPathComponent(effect)
            let soundURL = NSURL.fileURL(withPath: soundPath)

            //2 load the file contents
            var loadError:NSError?
            let player = AVAudioPlayer(contentsOfURL: soundURL, error: &loadError)
            assert(loadError == nil, "Load sound failed")

            //3 prepare the play
            player.numberOfLoops = 0
            player.prepareToPlay()

            //4 add to the audio dictionary
            audio[effect] = player
        }
    }
  1. Get the full path to the sound file and convert it to a URL by using NSURL.fileURLWithPath().
  2. Call AVAudioPlayer(contentsOfURL:error:) to load a sound file in an audio player.
  3. Set the numberOfLoops to zero so that the sound won’t loop at all. Call prepareToPlay() to preload the audio buffer for that sound.
  4. Finally, save the player object in the audio dictionary, using the name of the file as the dictionary key.

1 Answers

0
vadian On

Just replace resourcePath with resourceURL

let soundURL = Bundle.main.resourceURL!.appendingPathComponent(effect)

and you have to wrap the AVAudioPlayer initializer in a try block

func preloadAudioEffects(effectFileNames:[String]) {
    for effect in AudioEffectFiles {
        let soundURL = Bundle.main.resourceURL!.appendingPathComponent(effect)

        //2 load the file contents

        do {
           let player = try AVAudioPlayer(contentsOf: soundURL)
           //3 prepare the play
           player.numberOfLoops = 0
           player.prepareToPlay()

           //4 add to the audio dictionary
           audio[effect] = player

        } catch { print(error) }
    }
}