Here's my Swift 2.1 code snippet. The error that's occurring is shown in the comments at the point where the error appears.
The error shows up in the debugging panel, and the app crashes. The app never prints the line in the catch, nor does it gracefully return as expected.
let audioFileURL = receivedAudio.filePathURL
guard let audioFile = try? AVAudioFile(forReading: audioFileURL) else {
print("file setup failed")
return
}
let audioFileFrameCount = AVAudioFrameCount(audioFile.length)
audioFileBuffer = AVAudioPCMBuffer(PCMFormat: audioFile.fileFormat, frameCapacity: audioFileFrameCount)
do {
// ERROR: AVAudioFile.mm:263: -[AVAudioFile readIntoBuffer:frameCount:error:]: error -50
// Terminating app due to uncaught exception 'com.apple.coreaudio.avfaudio', reason: 'error -50'
// -50 = Core Audio: bad param
try audioFile.readIntoBuffer(audioFileBuffer)
}
catch {
print("unable to load sound file into buffer")
return
}
From everything I've seen, my do/try/catch format should be correct.
audioFile.readIntoBuffer
returns void
and has the keyword throws
.
Yet, the catch is never executed.
What am I missing?
UPDATE: From Apple's documentation on AVAudioFile
For:
func readIntoBuffer(_ buffer: AVAudioPCMBuffer) throws
Under Discussion:
HANDLING ERRORS IN SWIFT:
In Swift, this API is imported as an initializer and is marked with the throws keyword to indicate that it throws an error in cases of failure.
You call this method in a try expression and handle any errors in the catch clauses of a do statement, as described in Error Handling in The Swift Programming Language (Swift 2.1) and Error Handling in Using Swift with Cocoa and Objective-C (Swift 2.1).
From The Swift Programming Language (Swift 2.1): Error Handline
NOTE
Error handling in Swift resembles exception handling in other languages, with the use of the try, catch and throw keywords. Unlike exception handling in many languages—including Objective-C—error handling in Swift does not involve unwinding the call stack, a process that can be computationally expensive. As such, the performance characteristics of a throw statement are comparable to those of a return statement.
And, finally, from the same document:
Handling Errors Using Do-Catch
You use a do-catch statement to handle errors by running a block of code. If an error is thrown by the code in the do clause, it is matched against the catch clauses to determine which one of them can handle the error.
I don't have to write and throw my own errors/exceptions for them to be caught. I should be able to catch Swift's exceptions as well.