0

1these are the wav files I used

2I attached a screenshot of where it is throwing this error.

this is what I have right now. I thought I had everything correct. I know it has something to do with using an optional but not sure how to fix it.

import UIKit
import AVFoundation

class SecondViewController: UIViewController
{
    var audioPlayer: AVAudioPlayer?

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.

        do
        {
            let catSound = Bundle.main.path(forResource: "Cat", ofType: "wav")
            let horseSound = Bundle.main.path(forResource: "Horse", ofType: "wav")
            let dogSound = Bundle.main.path(forResource: "Dog", ofType: "wav")
            let raccoonSound = Bundle.main.path(forResource: "Raccoon", ofType: "wav")

            audioPlayer = try AVAudioPlayer(contentsOf: URL(fileURLWithPath: catSound!))
            audioPlayer = try AVAudioPlayer(contentsOf: URL(fileURLWithPath: horseSound!))
            audioPlayer = try AVAudioPlayer(contentsOf: URL(fileURLWithPath: dogSound!))
            audioPlayer = try AVAudioPlayer(contentsOf: URL(fileURLWithPath: raccoonSound!))
        }
        catch
        {
            print(error)///
        }
    }

    @IBAction func cat(_ sender: Any)
    {
        audioPlayer?.play()
    }
    @IBAction func horse(_ sender: Any)
    {
        audioPlayer?.play()
    }
    @IBAction func dog(_ sender: Any)
    {
        audioPlayer?.play()
    }
    @IBAction func raccoon(_ sender: Any){
        audioPlayer?.play()
    }
}
  • When you get that error, look for exclamation marks (`!`) which mean an optional is being force unwrapped. I think the path to your sounds is wrong. Also, you set the same audio player instance to each sound, so only the last one will stay. Try setting the sound in each of the button actions. – Chris Dec 03 '19 at 05:56
  • 1
    Does this answer your question? [What does "fatal error: unexpectedly found nil while unwrapping an Optional value" mean?](https://stackoverflow.com/questions/32170456/what-does-fatal-error-unexpectedly-found-nil-while-unwrapping-an-optional-valu) – Joakim Danielson Dec 03 '19 at 06:01
  • If possible can you please share the screenshot of the line where it is crashing. – ketaki Damale Dec 03 '19 at 06:02
  • replace `URL(fileURLWithPath: catSound!)` with optional instead of force unwrap. `URL(fileURLWithPath: catSound ?? "")`. Force unwrap will crash if its value is nil – tuyen le Dec 03 '19 at 06:26
  • Can you also share a screenshot of the audio files in Xcode – Sayooj Dec 03 '19 at 07:01
  • just uploaded a screenshot of the audio files – Lindsey Montgomery Dec 03 '19 at 07:18
  • My app doesnt crash anymore thanks to you, @Sayooj, but when i press the buttons the sound doesnt play. any idea why? – Lindsey Montgomery Dec 03 '19 at 07:25
  • @LindseyMontgomery The resource name in code should be the same as the ones in your bundle. In your code you have supplied "Cat" while the file name is "cat" `let catSound = Bundle.main.path(forResource: "cat", ofType: "wav")` . Can you change that and try – Sayooj Dec 03 '19 at 07:30
  • @Sayooj omg im crying, it worked. I literally have been stuck on this for 5 days and had a mentl breakdown. Thank you so so much!!! – Lindsey Montgomery Dec 03 '19 at 07:34
  • I will update my answer with the changes please mark the answer as accepted. – Sayooj Dec 03 '19 at 07:39

3 Answers3

1

As @Chris and @inexcitus mentioned, your complete code would look like.

class SecondViewController: UIViewController {

    var audioPlayer: AVAudioPlayer?
    override func viewDidLoad() {
      super.viewDidLoad()
    }

    @IBAction func cat(_ sender: Any)
    {
       if  let catSound = Bundle.main.path(forResource: "cat", ofType: "wav") {
           audioPlayer = try? AVAudioPlayer(contentsOf: URL(fileURLWithPath: catSound))
           audioPlayer?.play()
       }else {
        print("Cat File is missing")
       }

    }
    @IBAction func horse(_ sender: Any)
    {
       if  let horseSound = Bundle.main.path(forResource: "horse", ofType: "wav") {
          audioPlayer = try? AVAudioPlayer(contentsOf: URL(fileURLWithPath: horseSound))
          audioPlayer?.play()
       }else {
        print("Horse File is missing")
       }
    }


    @IBAction func dog(_ sender: Any)
    {
       if  let dogSound = Bundle.main.path(forResource: "dog", ofType: "wav") {
          audioPlayer = try? AVAudioPlayer(contentsOf: URL(fileURLWithPath: dogSound))
          audioPlayer?.play()
       }else {
        print("Dog File is missing")
       }
    }
    @IBAction func raccoon(_ sender: Any)
    {
       if  let raccoonSound = Bundle.main.path(forResource: "raccoon", ofType: "wav") {
          audioPlayer = try? AVAudioPlayer(contentsOf: URL(fileURLWithPath: raccoonSound))
          audioPlayer?.play()
       }else {
        print("Raccoon File is missing")
       }
   }}
Sayooj
  • 375
  • 3
  • 13
0

One of your resources is nil. You should check if your resoruce is nil before (forcefully) unwrapping it:

if let catSound = Bundle.main.path(forResource: "Cat", ofType: "wav")
{
    audioPlayer = try? AVAudioPlayer(contentsOf: URL(fileURLWithPath: catSound))
}

Do this for every resource and use the debugger to see which one is nil.

inexcitus
  • 2,471
  • 2
  • 26
  • 41
0

Case sensitivity matters.

The files are lowercased ("cat") but the parameter strings in the code are uppercased ("Cat"). The parameter string and the file name must match exactly.

Your code is not very useful anyway because it overwrites the audio player instance three times in viewDidLoad.

A more efficient solution is to create a method to load the file and play the sound and to use the URL related API of Bundle.

The force unwrapping is fine because all files must be in the bundle at compile time. A design mistake (file is missing or name is misspellt) can be fixed immediately.

class SecondViewController: UIViewController
{
    var audioPlayer: AVAudioPlayer!

    @IBAction func cat(_ sender: Any) {
        playSound(withName: "cat")
    }

    @IBAction func horse(_ sender: Any) {
        playSound(withName: "horse")
    }

    @IBAction func dog(_ sender: Any) {
        playSound(withName: "dog")
    }

    @IBAction func raccoon(_ sender: Any){
        playSound(withName: "raccoon")
    }

    func playSound(withName name : String) {
        let sound = Bundle.main.url(forResource: name, withExtension: "wav")!
        audioPlayer = try! AVAudioPlayer(contentsOf: sound)
        audioPlayer.play()
    }
}
vadian
  • 274,689
  • 30
  • 353
  • 361