0
votes

I am currently downloading an m4a file from firebase and trying to play the file with AVAudio Player.

How the system works

  1. Get path of downloaded file as String

let pathForAudio: String = UserDefaults.standard.string(forKey: "path") ?? "There is no path for the audio"

  1. Convert to URL

let url = URL(string: pathForAudio)

  1. Pass URL into AVAUDIOPLAYER Function

soundPlayer = try AVAudioPlayer(contentsOf: url!)

When doing soundPlayer.play() I get "Unexpectedly found nil while implicitly unwrapping an Optional value"

I have seen this problem on Stack Before and they just enable permissions on a static file. Here the file path always changes so I cannot perform their solution.

Any help is much appreciated, let me know if you need other code blocks. Thanks so much!

1
Is it a path “/some/thing” or a URI “file://some/thing” . If it’s the former you need URL(path: url)Warren Burton

1 Answers

0
votes

You define your path this way:

let pathForAudio: String = UserDefaults.standard.string(forKey: "path") ?? "There is no path for the audio"

This could result in:

  1. A valid file path stored in UserDefaults
  2. An invalid file path stored in UserDefaults
  3. Nothing stored in UserDefaults, which would then cause it to be "There is no path for the audio"

Unless you get scenario #1, then your next call (let url = URL(string: pathForAudio)) will fail, returning a nil value (which is what's happening right now. Then, upon calling try AVAudioPlayer(contentsOf: url!), because you're force unwrapping with !, you'll have a crash because you have a nil value that you're telling the system isn't nil by using !

In short, you need to put a valid path into UserDefaults in order for this system to work.

I'd also do some error checking along the way. Something like:

guard let pathForAudio = UserDefaults.standard.string(forKey: "path") else {
  //handle the fact that there wasn't a path
  return
}

guard let url = URL(string: pathForAudio) else {
  //handle the fact that a URL couldn't be made from the string (ie, invalid path
  return
}

//see if the file exists
guard FileManager.default.fileExists(atPath: pathForAudio) else {
  //handle no file
  return
}

do {
  soundPlayer = try AVAudioPlayer(contentsOf: url) //notice there's now no !
} catch {
  //handle error
  print(error)
}