Welcome to another short tutorial from our Translating between ActionScript and Objective-C series. I’ve lined up an exceptional article for you.
… which is mostly to say that today we will be dealing with exceptions.
What was covered so far?
- We started with an introduction of what to expect from the series and how tutorials will be structured
- Then we laid some ground work and saw how ActionScript data is represented in C
- You got your hands dirty by implementing a shortcut for sending events from iOS to AIR
- And have another one-liner that checks FREResult for you.
What will this part cover?
Today’s addition to your library of auxiliary functions looks like this:
1 |
BOOL hasThrownException( FREObject thrownException ) |
What does it do for you? A lot of the AIR C API functions can throw exceptions, but not the traditional way. Instead of immediately stopping the flow of code, exceptions are “returned” as output parameters. For example, the FRESetObjectProperty function takes a pointer to an exception object (FREObject, really), in which to put exception information, should an exception occur:
1 2 |
FREObject thrownException = NULL; FREResult status = FRESetObjectProperty( objAS, propertyName, propertyValue, &thrownException ); |
This exception object, being hidden behind a FREObject (see this post for a detailed look behind the curtain of the FREObject), will need some processing before it can tell you what happened. The auxiliary function you are implementing today will do that for you and save you the need to do a lot of multiline checks after each AIR API call in your native iOS code.
Wait. What’s an exception?
If you are new to exceptions: you can think of an exception as an event. When thrown or dispatched, it disrupts the normal flow of code. For example: if a call to AIR in the middle of one of your functions throws an exception, the rest of the code in that function will not be executed. Execution will instead be
passed to an exception handler if one is found in your function or the function that called it or the function that called the one that called it… If no exception handler is found, your app will likely be terminated. An exception handler is usually implemented as a try-catch statement.
The implementation
Ass you will see, getting information about the exception takes a few lines of code, which you probably don’t want to repeat over and over either. The hasThrownException auxiliary function below will save you the need to. It checks if an exception was indeed thrown and if one was, tries to get information about it and pass it back to ActionScript:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
#pragma exceptions /** * Checks if a call to a FRE* function threw an exception * and if an exception is caught, sends an error event to ActionScript. * * @param thrownException The exception instance. * * @return TRUE if an exception was caught, FALSE otherwise */ BOOL hasThrownException( FREObject thrownException ) { if ( NULL == thrownException ) { // No exception was thrown. All clear. return FALSE; } // Check if we caught a valid exception object first: FREObjectType objectType; if ( FRE_OK != FREGetObjectType( thrownException, &objectType ) ) { NSLog( @"Exception was thrown, but failed to obtain information about its type" ); sendMessage( MSG_ERROR, @"Exception was thrown, but failed to obtain information about its type" ); return TRUE; } // If the exception object is valid, then get the exception information as a string: if ( FRE_TYPE_OBJECT == objectType ) { FREObject exceptionTextAS = NULL; FREObject newException = NULL; if ( FRE_OK != FRECallObjectMethod( thrownException, ( const uint8_t * ) "toString", 0, NULL, &exceptionTextAS, &newException ) ) { NSLog( @"Exception was thrown, but failed to obtain information about it" ); sendMessage( MSG_ERROR, @"Exception was thrown, but failed to obtain information about it" ); return TRUE; } // Send an event to ActionScript with information on the exception: NSString * exceptionText = getNSStringFromFREObject( exceptionTextAS ); sendMessage( MSG_ERROR, [ NSString stringWithFormat: @"exception: %s", ( uint8_t * ) [ exceptionText UTF8String ] ] ); return TRUE; } return FALSE; } |
Result
Instead of performing all of these checks after every AIR C API call in your native code, you now have a one-liner call that will do it for you. Check the next article on setting ActionScript object properties in your native code to see examples of how to use it.
Leave a Reply