0

Lets say we have an app that we are about to submit to the app store... but it contains the following code:

    try? audioSession.setCategory(AVAudioSessionCategoryAmbient)
        if error != nil {
        // this should never happen
        }

    try? audioSession.setActive(true)
        if error != nil {
        // this should never happen
        }

We have to "try" the setCategory method because it "throws" ... but I have no idea why it would ever throw/fail.

I feel like this will be viewed as trash code... and that I should be doing more than just saying "this should never happen," but if an error did happen, I would have no idea what to do with it.

This documentation doesn't give any reasons why there would be an error, either.

Am I supposed to make a pop-up window that says "sorry... we encountered an error while attempting to set the category on the audioSession singleton instance... but the reason for this error is beyond this app's control. Press OK so the app can close. This never happened during app testing... so I have no idea why it happened to you now... must have something to do with your device. Maybe reboot? Better luck next time."

Or am I supposed to "elegantly handle the error?" How can I do that when I don't know what the potential error "throws" are and more importantly the potential reasons behind them.

Thanks for any suggestions. :)

Milan Nosáľ
  • 19,169
  • 4
  • 55
  • 90
Nerdy Bunz
  • 6,040
  • 10
  • 41
  • 100

3 Answers3

1

If there is even a remote chance this might happen, and even though you have no proper way to handle it (let us say that the app is built upon that feature and if it is not working then the app becomes useless) - even then I would recommend putting there some nice handling code - I believe it's better than just let the app crash.

I would probably ask the user to report this to you with some details on their setup (after all, the error itself should contain at least a message that might give you a hint what went wrong).

If the app crashes, I would just assume the developer made some mistake. If a popup tries to at least broadly explain that there were some problems with obtaining an audio session, I would at least know that the developer tried to do something about it.

Basically, while you cannot do anything about recovering from the error, you can do at least something about user experience.

Milan Nosáľ
  • 19,169
  • 4
  • 55
  • 90
  • But how do you continue running your app? Will you tell the user to please force-close it and start over? – luk2302 Jan 18 '18 at 10:27
  • well, I would probably recommend the user to try to reboot the device, but I would force close it myself, maybe just implement some "refresh" button to try to get the audioSession again – Milan Nosáľ Jan 18 '18 at 10:29
  • Reboot the device just because your app encountered an error? That would be a fast track to deletion on my iPhone. – JeremyP Jan 18 '18 at 10:37
  • 1
    good point.. I'm contradicting myself here.. I'm not a support specialist, all I can remember from the topic is "have you tried to turn it off and on again?" – Milan Nosáľ Jan 18 '18 at 10:39
1

I see two strategies that you could adopt.

  • Assume that the only way to throw an error is to pass in an invalid category string. Since your string is hard coded to one of the supplied constants, you can assume this will never happen. In this case, make the try cause a fatal error if it throws. e.g.

    try! audioSession.setCategory(AVAudioSessionCategoryAmbient)
    

    or

    do 
    {
        try audioSession.setCategory(AVAudioSessionCategoryAmbient)
    }
    catch
    {
         fatalError("setCategory failed with error: \(error)")
    }
    
  • Assume there may be some local reason why it hasn't worked. In this case, use a do ... catch to catch the error and report it to the user. This doesn't have to happen in the function that calls audioSession.setCategory, you can choose to allow it to throw and allow other functions in the call stack to throw until you get to a point where you can easily report the error. If you get to this point, make sure the intermediate throwing functions are capable of clearing up their state by using defer and catch blocks.

JeremyP
  • 84,577
  • 15
  • 123
  • 161
1

If you are sure errors will never occur you can force try

try! audioSession.setCategory(AVAudioSessionCategoryAmbient)
try! audioSession.setActive(true)
iDeveloper
  • 140
  • 10