0
votes

I am using Xcode 7.0.1 Swift 2 iOS 9. While playing sound I get this error:

"fatal error: unexpectedly found nil while unwrapping an Optional value"

Error Screenshot

and this is my code:

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    playSound(enumerator![indexPath.item] )
}

func playSound(soundName: String)
{
    let coinSound = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource(soundName, ofType: "m4a")!)
    do{
        let audioPlayer = try AVAudioPlayer(contentsOfURL:coinSound)
        audioPlayer.prepareToPlay()
        audioPlayer.play()
    }catch {
        print("Error getting the audio file")
    }
}
3
in which line u get the errorAnbu.Karthik
There you go, fixed the image for you.GoodSp33d

3 Answers

0
votes

NSBundle pathForResource(name: String?, ofType ext: String?) -> String? returns an optional, and you are force unwrapping. Either your path is wrong or your resource is not there.

And looking at the image sound name has .m4a extension. If you want to provide extension yourself, you can skip ofType and pass nil or separate the extension from the name of the resource and send both parameters.

To be safe, you should always check for optionals when you are not sure if it has value or not

let pathComponents = soundName.componentsSeparatedByString(".")
if let filePath = NSBundle.mainBundle().pathForResource(pathComponents[0], ofType: pathComponents[1]) {
    let coinSound = NSURL(fileURLWithPath: filePath)
}
0
votes

The reason this is crashing even though your function is safely checking the validity of it's data is because you are force unwrapping your enumerator object, which crashes before the function is called. You need to check that one safely as well!

Or, as I just glanced as your code again the sound object is never being created (probably not being found in the bundle or incorrect name) and then when you try to force unwrap that, it could also crash. Is your print statement ever printed?

0
votes

The audioPlayer constant you have delcared in the playSound function gets dealloacted as soon as the playSound function completes.

Declare the audioPlayer as a property at the class level and they play the sound.

Here is the sample code :

class ViewController: UIViewController {

var audioPlayer = AVAudioPlayer()

...........

func playSound(soundName: String) {

    let coinSound = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource(soundName, ofType: "wav")!)
    do{
        audioPlayer = try AVAudioPlayer(contentsOfURL:coinSound)
        audioPlayer.prepareToPlay()
        audioPlayer.play()
    }catch {
        print("Error getting the audio file")
    }
}