For whom this post is? We’re targeting ANE developers specifically in this post, and talking about how to develop ANEs not how to use them! So if you’re an AIR developer who doesn’t develop AIR Native Extensions, you may find this reading unrelated to ANE usage or a little bit confusing.
Developing AIR Native Extensions is fun but there are times when things can get too messy (if you’re not familiar how to handle it!) especially when your project requires several ANEs. These ANEs may conflict with each other in obvious or hidden ways. Obvious conflicts are the easy ones, you can just rename your methods in Xcode and avoid them but the hidden conflicts may keep you running for some unpredictable bugs in your project. A simple example is when you have two ANEs in your project and they are both listening for an event like “didReceiveLocalNotification“. In iOS side of your ANEs, you are overriding Events like that on the native side to be able to have access to them on the AIR side. But what would happen if the first ANE is overriding the native method and then the second ANE overrides the same native method? As you may have guessed, the first ANE will loose access to the method.
This is why we have created the OverrideAir.ane. OverrideAir.ane will be the first ANE which will override the native methods. Then, it will dispatch them to any other ANE which might request the events. This way, other ANEs can easily have access to the native methods without worrying about deactivating them in other loaded ANEs.
That said, overriding native methods is not the only job of this ane. It has other cool powers listed below which makes things easy for ANE developers.
Overriding Native methods (iOS)
Taking care of data conversions between AIR and native sides (Android+iOS)
Unified logging system (Android+iOS)
In this post you will learn how to implement this useful small utility in your ANE development process. Please note that I am considering readers of this article to be well familiar with how ANEs are developed. This post is not a beginner guide. It’s an advanced one.
iOS Implementation
Click here to download the static .a library and the header file. And add them to your own Xcode project. There’s a cache here though, you should make sure that libexOverrideNative.a is not linked in your final extension build. Why? Because you need it in your Xcode only to be able to use the methods; but your final project, the AIR app, will use the actual OverrideAir.ane to reference to. If you forget to remove the linkage to the .a library from your Xcode build, you will receive some conflict error messages when building your final AIR app.
So, to have access to overrideAir methods, simply import it in your obj-C classes like this: #import “MyFlashLabsClass.h” .
Android Implementation
Click here to download the .jar library. And place it in your AndroidStudio project’s libs folder and add the following line to your module’s gradle compile files(‘libs/overrideAdobe.jar’)
Finally to have access to its methods, import the library:
Just like the iOS side, make sure you are not packaging the .jar file in your own ANE build. You should ignore that and your final build will have access to it because you are embedding the overrideAir.ane in your project anyhow.
Listening to Native method delegates (iOS)
As an example, if you wish to listen to a native method like didFinishLaunchingWithOptions, You need to prepare your native side of your native extension to listen for the following String command: checkOverride_didFinishLaunchingWithOptions
NOTE: Don’t get confused please!, to call a native method from Actionscript side you normally do it like: _context.call(“functionname”, “argument”); . correct? and on your native side, you will wait for the “functionname” to be called. This is basically the same, you must wait for checkOverride_didFinishLaunchingWithOptions to happen.
As soon as the target event is called on the native side, you can have access to its parameters like the following example. In this example, we are checking if the application has been launched by icon touch, or maybe because the user has opened the app from touching on a localNotifiction!
-(void)checkOverride_didFinishLaunchingWithOptions
{
UILocalNotification *localNotif = [[[MyFlashLabsClass sharedInstance] retriveLaunchingOptions]
objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
if (localNotif)
{
NSLog(@"We have a localNotification....");
}
else
{
NSLog(@"No notification available when launched");
}
}
Below is the list of native methods which you can listen to from your ANEs:
When any of the above methods happen, they will have one or more arguments which you may wish to have access to. you can easily have access to them using [MyFlashLabsClass sharedInstance] . For example, when checkOverride_didReceiveLocalNotification happens, you can have access to the native argument of this event by calling: UILocalNotification *localNotif = [[MyFlashLabsClass sharedInstance] retriveLocalNotification];
I’m sure you are now asking a question… how do these methods will be called from the AIR side to begin with? Well, the OverrideAir.ane will take care of this again but with a little of your help. In your own ANE, you need to let OverrideAir.ane know that you need to listen to the overridden methods. And how you can do that? it’s super easy. First create a Class variable like this private var OverrideClass:Class; then call OverrideClass = getDefinitionByName(“com.myflashlab.air.extensions.dependency.OverrideAir”) as Class; And finally pass over your ExtensionContext to the overrideAir ANE like this: if (os==iOS) OverrideClass[“initForInternalUse”](_context);
We are accessing the OverrideAir class like this, because this way, you won’t be annoyed when building the swc side of your ANE. The OverrideAir class will be accessed at runtime not the compile time.
var OverrideClass:Class;
OverrideClass = getDefinitionByName("com.myflashlab.air.extensions.dependency.OverrideAir") as Class;
// let Override ANE know that this ANE needs access to iOS overrides
if (os == iOS) OverrideClass["initForInternalUse"](_context);
How to efficiently override native methods in AIR Native Extensions
Developing AIR Native Extensions is fun but there are times when things can get too messy (if you’re not familiar how to handle it!) especially when your project requires several ANEs. These ANEs may conflict with each other in obvious or hidden ways. Obvious conflicts are the easy ones, you can just rename your methods in Xcode and avoid them but the hidden conflicts may keep you running for some unpredictable bugs in your project. A simple example is when you have two ANEs in your project and they are both listening for an event like “didReceiveLocalNotification“. In iOS side of your ANEs, you are overriding Events like that on the native side to be able to have access to them on the AIR side. But what would happen if the first ANE is overriding the native method and then the second ANE overrides the same native method? As you may have guessed, the first ANE will loose access to the method.
This is why we have created the OverrideAir.ane. OverrideAir.ane will be the first ANE which will override the native methods. Then, it will dispatch them to any other ANE which might request the events. This way, other ANEs can easily have access to the native methods without worrying about deactivating them in other loaded ANEs.
That said, overriding native methods is not the only job of this ane. It has other cool powers listed below which makes things easy for ANE developers.
In this post you will learn how to implement this useful small utility in your ANE development process. Please note that I am considering readers of this article to be well familiar with how ANEs are developed. This post is not a beginner guide. It’s an advanced one.
iOS Implementation
Click here to download the static .a library and the header file. And add them to your own Xcode project. There’s a cache here though, you should make sure that libexOverrideNative.a is not linked in your final extension build. Why? Because you need it in your Xcode only to be able to use the methods; but your final project, the AIR app, will use the actual OverrideAir.ane to reference to. If you forget to remove the linkage to the .a library from your Xcode build, you will receive some conflict error messages when building your final AIR app.
So, to have access to overrideAir methods, simply import it in your obj-C classes like this: #import “MyFlashLabsClass.h” .
Android Implementation
Click here to download the .jar library. And place it in your AndroidStudio project’s libs folder and add the following line to your module’s gradle compile files(‘libs/overrideAdobe.jar’)
Finally to have access to its methods, import the library:
Just like the iOS side, make sure you are not packaging the .jar file in your own ANE build. You should ignore that and your final build will have access to it because you are embedding the overrideAir.ane in your project anyhow.
Listening to Native method delegates (iOS)
As an example, if you wish to listen to a native method like didFinishLaunchingWithOptions, You need to prepare your native side of your native extension to listen for the following String command: checkOverride_didFinishLaunchingWithOptions
As soon as the target event is called on the native side, you can have access to its parameters like the following example. In this example, we are checking if the application has been launched by icon touch, or maybe because the user has opened the app from touching on a localNotifiction!
Below is the list of native methods which you can listen to from your ANEs:
When any of the above methods happen, they will have one or more arguments which you may wish to have access to. you can easily have access to them using [MyFlashLabsClass sharedInstance] . For example, when checkOverride_didReceiveLocalNotification happens, you can have access to the native argument of this event by calling: UILocalNotification *localNotif = [[MyFlashLabsClass sharedInstance] retriveLocalNotification];
Feel free to explore the header file.
I’m sure you are now asking a question… how do these methods will be called from the AIR side to begin with? Well, the OverrideAir.ane will take care of this again but with a little of your help. In your own ANE, you need to let OverrideAir.ane know that you need to listen to the overridden methods. And how you can do that? it’s super easy. First create a Class variable like this private var OverrideClass:Class; then call OverrideClass = getDefinitionByName(“com.myflashlab.air.extensions.dependency.OverrideAir”) as Class; And finally pass over your ExtensionContext to the overrideAir ANE like this: if (os==iOS) OverrideClass[“initForInternalUse”](_context);
We are accessing the OverrideAir class like this, because this way, you won’t be annoyed when building the swc side of your ANE. The OverrideAir class will be accessed at runtime not the compile time.
Enjoy building beautiful AIR apps 🙂
With ♥
Myflashlabs Team
Share this:
Related