0

So, I'm using this function to set AVAudioPlayer:

func setupAudioPlayerWithFile(file: String) -> AVAudioPlayer? {
    var audioPlayer: AVAudioPlayer?
    if let sound = NSDataAsset(name: file) {
        do {
            try! AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryAmbient)
            try! AVAudioSession.sharedInstance().setActive(true)
            try audioPlayer = AVAudioPlayer(data: sound.data, fileTypeHint: AVFileTypeWAVE)
        } catch {
            print("error initializing AVAudioPlayer")
        }
    }
    return audioPlayer
}

But I'm getting hundreds of reported crashes from users. I'm not able to replicate any crash.

The crashes happen on these two lines:

try! AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryAmbient)
try! AVAudioSession.sharedInstance().setActive(true)

sometimes it crashes on the first line, sometimes on the second. How do I fix this? What could be causing these crashes?

TimSim
  • 3,936
  • 7
  • 46
  • 83
  • You shouldn't use `try !` if you're wrapping your code in a `do` block. Just use `try`. – JAL Apr 09 '17 at 00:28
  • Yes, that's one half of the problem, but I'd also like to know what caused those crashes. – TimSim Apr 09 '17 at 00:39

1 Answers1

1

Actually, I have no idea of what's the reason of causing the crash(es), but to prevent them, you should replace the try! with try in the do block to let catch to be able for handling any expected error. Currently, the do catch is only handling the try audioPlayer = AVAudioPlayer, try! AVAudioSession and try! AVAudioSession should do cause a crash if something wrong happened.

To be more clear, consider the following example:

enum FirstError: Error {
    case FirstError
}

func throwFirstErrorFunction() throws {
    throw FirstError.FirstError
}

enum SecondError: Error {
    case SecondError
}

func throwSecondErrorFunction() throws {
    throw SecondError.SecondError
}

Case #1:

try! throwFirstErrorFunction() // crash

The application should get a crash.

Case #2:

do {
    try throwFirstErrorFunction()
    //try throwSecondErrorFunction()
} catch (let error) {
    print(error) // FirstError
}

It should print FirstError.

Case #3 (what are you facing):

do {
    try! throwFirstErrorFunction() // crash
    try throwSecondErrorFunction()
} catch (let error) {
    print(error)
}

The application should get a crash, why? because the do catch handles only try but not try!.

Case #4 (solution):

do {
    try throwSecondErrorFunction()
    try throwFirstErrorFunction()
} catch (let error) {
    print(error) // SecondError
}

It should print SecondError. Note that the first caught error will get handled -by the catch block- and the other trys should be skipped.

Also,

I'd recommend to check try, try! & try? what’s the difference, and when to use each?

Community
  • 1
  • 1
Ahmad F
  • 30,560
  • 17
  • 97
  • 143