Buy any Easy Native Extensions 2nd Edition package and get our $99 iOS + Android ANE Template completely free before the end of June 2015.
- step-by-step guide to making your iOS extension in under an hour
- library for data conversion between ActionScript and native code
- tutorials
- infographics
- code included
When you make a native extension using the AIR C API, your native code tends to have two parts:
- one that’s concerned with exposing functionality in a way that AIR can call, in other words, dependent on the AIR C API;
- functional part, which deals with the platform-specific stuff. This part of your code doesn’t (and shouldn’t) care about whether it’s used in an AIR native extension, a purely native app or something else.
Ideally you want to keep the dependency between these two parts one-directional: the AIR-concerned part should depend on the functional part, but the functional part should not know about and depend on AIR. If you decide to reuse your, say camera or speech recognition functionality, in another project that’s not AIR-related , you don’t want to force that to include the AIR C API.
So, what happens if you need to dispatch an event from the functional part of your code? Say, the camera refused to start or the speech processor is ready with results and you want you alert AIR to this…
Do you make your functional code include FlashRuntimeExtensions.h and call this?
1 |
FREResult FREDispatchStatusEventAsync(FREContext ctx, const uint8_t* code, const uint8_t* level); |
No way.
Encapsulate thy code
So how do you send an event from the functional part of your code without making it dependent on FlashRuntimeExtensions.h and the AIR C API?
Here is one neat way:
1. Encapsulate the event dispatching in your AIR-dependent code by defining a function that takes the relevant event information and doesn’t require the caller to pass in a FREContext instance or expect a FREResult in return:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
void sendMessage( const NSString * const messageType, const NSString * const message ) { assert( messageType ); assert( g_ctx ); if ( NULL != message ) { FREDispatchStatusEventAsync( g_ctx, ( uint8_t * ) [ messageType UTF8String ], ( uint8_t * ) [ message UTF8String ] ); } else { FREDispatchStatusEventAsync( g_ctx, ( uint8_t * ) [ @"STATUS_EVENT" UTF8String ], ( uint8_t * ) [ messageType UTF8String ] ); } } |
Here g_ctx is a pointer to the ExtensionContext that your AIR-dependent code keeps.
2. Make sendMessage() available for calling from your AIR-independent code by declaring it as an extern function (in your AIR-independent code):
1 |
extern void sendMessage( const NSString * const messageType, const NSString * const message ); |
3. Call sendMessage() from your AIR-independent code. For example:
1 |
sendMessage( MSG_INFO, [ NSString stringWithFormat: @"No audio tracks found in %@", fromVideo ] ); |
What else?
See how to send events from Objective-C to ActionScript.
See how to send events from Java to ActionScript.
Do you need a copy of FlashRuntimeExtensions.h in your project?
Over to you
What coding and design principles do you adhere to?
Tell us in the comments below.
Leave a Reply