Swift 2: Can't find audio file path when I use variables as file names

Here's a very strange phenomenon that I'm struggling with:

I'm trying to play an audio file on a button click based on a certain context. For instance if the condition "A" I'll play a certain sound (on button click) and if it is "B" I'd play another sound. I use a switch statement to decide what sounds are played for which condition.


The problem: Even though I'm getting the conditions to work correctly, the AVAudioPlayer always returns nil. But when I hard-code the file to be played, it works just fine. It is only when I use a variable to decide which sound to be played "in the switch statement" is when the sound doesn't play, else when I use a static variable without changing its value, it works fine.


Here's my code: (It is called when a button is clicked and depending upon a condition such as time or day it will play a certain sound using files I've added)


func playSound(Condition: String){ 
     switch Condition { 
          case "1": 
               soundName = "1" 
          case "2": 
               soundName = "2" 
          case "3": 
               soundName = "3" 
          case "4": 
               soundName = "4" 
          case "5": 
               soundName = "5" 
          default: 
               soundName = "default" 
     } 
     let pathString = NSBundle.mainBundle().URLForResource(soundName, withExtension: "m4a")?.path // hardcoding soundName makes it work

     if let soundFilePath = pathString { 
          let sound = NSURL.fileURLWithPath(soundFilePath) 
          do { 
               audioPlayer = try AVAudioPlayer(contentsOfURL:sound) 
               audioPlayer.prepareToPlay() audioPlayer.play() 
          }catch { 
               print("Error getting the audio file") 
               } 
          } else { 
               print("Error: Can't find file. Path is nil") / 
     } 
}


Can anyone please help me figure out why? Is the switch taking too long? I doubt because I can print the value of the condition before I play the sound. Thanks in advance.

Accepted Reply

Got it to work. I guess the problem was with the files. Re-did everything and now its working. Thanks guys.

Replies

What are the sound file durations?


Which device are you testing on?


Have you nslog'd the path when not found?


Why are cases 3 & 4 duplicates?

This is just symbolic code.

Can you paste in a minimal snippet of the real code?

To be clear, the problem you’re having here is that

pathString
is nil, thus the AV Foundation code is irrelevant. What we need to see is the code that sets up
pathString
. It’d be great if you could paste in two snippets, one showing the failing code and one showing how things work when you hard-code
soundName
.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

The code is the real code - I've just changed the names of variables. The way the code works is there's a button on the UI, when someone pushes it, it calls the function I've shared. The argument the function takes in is a string based on what day it is - for instance if it is Monday, then Monday will be passed in. Based on this argument, the function will pick a sound file to play. If I hard code a sound file, it plays perfectly. When I allow the function to choose (the correct choice is made) but pathstring resolves to nil and no sound is played. So:


This works:

func playSound(Condition: String){
     switch Condition {
          case "1":
               soundName = "1"
          case "2":
               soundName = "2"
          case "3":
               soundName = "3"
          case "4":
               soundName = "4"
          case "5":
               soundName = "5"
          default:
               soundName = "default"
     }
     let pathString = NSBundle.mainBundle().URLForResource("3", withExtension: "m4a")?.path // hardcoding soundName makes it work

     if let soundFilePath = pathString {
          let sound = NSURL.fileURLWithPath(soundFilePath)
          do {
               audioPlayer = try AVAudioPlayer(contentsOfURL:sound)
               audioPlayer.prepareToPlay() audioPlayer.play()
          }catch {
               print("Error getting the audio file")
               }
          } else {
               print("Error: Can't find file. Path is nil")
     }
}

As a matter of fact, even this works:

func playSound(Condition: String){ 
     switch Condition { 
          case "1": 
               soundName = "1" 
          case "2": 
               soundName = "2" 
          case "3": 
               soundName = "3" 
          case "4": 
               soundName = "4" 
          case "5": 
               soundName = "5" 
          default: 
               soundName = "default" 
     } 

     let file = "5"
     let pathString = NSBundle.mainBundle().URLForResource(file, withExtension: "m4a")?.path // hardcoding soundName makes it work 

     if let soundFilePath = pathString { 
          let sound = NSURL.fileURLWithPath(soundFilePath) 
          do { 
               audioPlayer = try AVAudioPlayer(contentsOfURL:sound) 
               audioPlayer.prepareToPlay() audioPlayer.play() 
          }catch { 
               print("Error getting the audio file") 
               } 
          } else { 
               print("Error: Can't find file. Path is nil") / 
     }

This does NOT work:

func playSound(Condition: String){
     switch Condition {
          case "1":
               soundName = "1"
          case "2":
               soundName = "2"
          case "3":
               soundName = "3"
          case "4":
               soundName = "4"
          case "5":
               soundName = "5"
          default:
               soundName = "default"
     }
     let pathString = NSBundle.mainBundle().URLForResource(soundName, withExtension: "m4a")?.path // hardcoding soundName makes it work

     if let soundFilePath = pathString {
          let sound = NSURL.fileURLWithPath(soundFilePath)
          do {
               audioPlayer = try AVAudioPlayer(contentsOfURL:sound)
               audioPlayer.prepareToPlay() audioPlayer.play()
          }catch {
               print("Error getting the audio file")
               }
          } else {
               print("Error: Can't find file. Path is nil") /
     }
}

This is the actual code - I've just replaced file names ... condition is a string based on what time / day it is. The condition is correctly passed. The code for the button click is as follows:


@IBAction func soundButtonPressed(sender: UIButton) {
        playSound(today)
}


and today is set in ViewDidLoad() by the day of the week using NSDate and its formatter. Spits out a date in the format "EEEE" as string.

Got it to work. I guess the problem was with the files. Re-did everything and now its working. Thanks guys.

You might want to explain what you had to do, exactly, should someone else have a similar issue.


Thanks for the followup and good luck w/your app(s)..


Ken