20 tips for creating Air Native Extensions for iOS

Over the past three months I’ve created three Air Native Extensions for iOS (available on Github), which were all used in our game Stick Cricket Super Sixes, and have discovered a lot along the way. I’ve forgotten some of it, but here’s a few of the tips I can remember for anyone else approaching this task.

Documentation

1. Getting Started

Here’s a couple of useful getting started guides. If you don’t know what you’re doing, this is a good place to start. There are more on the web, just ask Google.

2. Read Adobe’s documentation.

For the most part Adobe’s documentation is comprehensive and detailed. Use it.

Writing the Actionscript code

3. Pay attention to the Actionscript API

Make an Actionscript API that suits the functionality you’re implementing. Don’t get pulled into copying Apple’s iOS API in Actionscript if there’s a better, more Actionscript like, way to do it.

Remember, changing the implementation later only affects the extension, but changing this API breaks all projects that use the extension so make it as good as you can.

4. Maximise the error checking in your Actionscript code

You need to check the input to your extension methods to avoid errors. You could do this in the native code, but it’s a lot easier to do it in the Actionscript code. If you know you’ll always call the native code with the correct number of parameters, and that those parameters will always be valid values, you can avoid a lot of error checking in the native code.

Of course, if you enjoy writing error checking code in C, go right ahead. Personally, I prefer to do this in Actionscript.

5. Always create a default implementation

Even if you’re only planning to use your extension on iOS, create a default implementation anyway. You build this default implementation in pure Actionscript, so it works on all platforms. It implements the same API as the iOS version, but using only Actionscript. That means it may throw errors or returns null values, but it will be valid Actionscript code that you can compile against for platforms other than iOS.

Without a default implementation, you can only ever test your app on an iOS device. This makes testing your app during development very tiresome. Being able to compile your app for desktop Air to test a new feature that’s unrelated to your native extension is very useful.

Writing the native code

6. Use Objective-C to interface to Apple’s APIs.

You don’t have to use Objective-C, but if you’re interfacing with any of Apple’s APIs it’s easier if you do. Otherwise, you can use C or C++.

7. Place the C code for the Air-Native interface in a .m file.

The interface between the native code and Air is via C, so your native code will include one file of C code to provide this interface. If you place this code inside a .c file, you can’t use any Objective-C functionality in there (e.g. you can’t use objective-c style code to call objective-c APIs), but if you place it inside a .m file you can. So life is easier if you use a .m extension.

8. The .m file containing the Air-Native interface doesn’t need a .h header file.

But you’ll want to disable the error messages so turn off warnings for “missing function prototypes” in your XCode project settings.

9. Use unique names for your extension initializer and finalizer functions.

A number of example extensions use generic names like “extInitializer” and “extFinalizer” for the initializer and finalizer functions. No two extensions in your project may have the same names for these functions, so use names that are appropriate to your project.

10. Use macros in your source code

How many times can you type

FREObject someFunction(FREContext context, void* functionData, uint32_t argc, FREObject argv[])

before you want to poke yourself in the eye with a blunt stick? Create a macro for this, and any other repetitive tasks for implementing the Air-Native interface. You can see a few of my macros in this source file. (Thank you to David Wagner for some of these.)

11. Set “Enable linking with shared libraries” to yes

There’s a lot of noise around the web about this XCode project setting, with some saying use “no” and some saying use “yes”. Basically, setting this to yes means your extension will be linked with the required libraries later when you compile your app. This is what you want. But it means when you compile your Air app that uses your native extension, you’ll need to direct the compiler to the iOS SDK so it can link to the libraries. See item 18 below.

N.B. If you get a build error

ld warning: unexpected srelocation type 9

then you probably either have this setting as no or you haven’t specified the location of the iOS SDK when building your app.

12. Be careful with threads

Your native extension can’t create Actionscript objects in any but the main thread from which it is called, and must do so during a call from Air. This makes using blocks in your objective-c code problematic. However, there is one thing you can do from another thread, and that is dispatch an event to the Actionscript ExtensionContext. This offers a solution

  1. In your block or other threaded code, store your data into a native object.
  2. Dispatch an event to your ExtensionContext with whatever details it needs for step 3.
  3. In response to the event, call a native method to fetch the object.
  4. In this native method, create the Actionscript object from the native object created in step 1 and return it.

13. Creating native views

Your Air application runs inside a standard native window. You can get a reference to this window as

[UIApplication sharedApplication].keyWindow

Once you have this window reference you can add subviews to it to display native views.

Compiling the Extension

14. Automate the compiling and testing of your extension

When building my Game Center extension I created a simple air app for testing the extension.

I created an ant build script to compile the whole extension (build the native C/obj-C library, build the native AS3 library, build the default AS3 library, wrap them all as an Air native extension) and to build the test project.

The result, one click in Eclipse and I had the extension built and the test project built against it, ready to drop on my phone (and using the Organiser in XCode makes this last step easy too). The result – it took about 10 seconds to go from writing code to having the test project with the latest extension on my phone. That’s still 9 seconds too long but it’s a lot better than most workflows I’ve seen.

Maybe there’s a better way if you use Flash Builder (I use FDT), and you certainly don’t have to use Ant – any build tool will do. But streamline the build and test process as much as you can. My ant scripts are in my Game Center extension project if you want them.

15. Using a third party library

If you’re using a third party library in your extension (e.g. the Flurry analytics library in my Flurry extension), include that library along with your compiled native library in the “-platform iPhone-ARM” argument when compiling the extension.

16. You may need a platform.xml file.

If using any but the most common libraries in the iOS SDK, create a platform.xml file to specify the libraries you’re using and the minimum iOS version to build against.

I create a platform.xml file for all my extensions – it hides the warning about unknown minimum iOS version that Air 3.1 will display if you don’t.

Building your mobile application

17. If your IDE doesn’t know about native extensions, use the .swc from the default implementation.

This swc contains the full Actionscript API of the native extension in a pure Actionscript implementation, so you can code against it, and compile with it for testing on your dev computer.

Of course, an IDE that doesn’t know about native extensions won’t build your mobile app correctly, but you’re using a build script for that aren’t you.

18. Specify the location of the iOS SDK when compiling your Air mobile app.

By default, the Air compiler compiles against version 4.0 of the iOS SDK. If your native extension uses features that don’t exist in this version it will fail to compile because the required libraries can’t be found. Specify the location of a later version of the iOS SDK to enable this linking. See this blog post for more details.

In Flash Builder, there is a setting for this somewhere in the various screens for configuring the native extensions your project uses. If you’re using the command line compiler, use the -platformsdk compiler flag to specify the path to the iOS SDK.

Unfortunately, this is only possible if you’re compiling your app on Mac OS X. Adobe are, apparently, working to get this working on Windows too. If you try to use a native extension that requires you to link to the SDK and don’t link to it, you will get a compile error like this (the second line may or may not be present).

Compilation failed while executing : ld64
ld: unknown option: -ios_version_min

Unfortunately, this means that for the time being some native extensions can only be used if you compile on a Mac.

19. ld: warning: ARM function not 4-byte aligned

When compiling your app, you may get a number of warnings of the form

ld: warning: ARM function not 4-byte aligned

These are just warnings and nothing to worry about. 4-byte alignment is an optimisation rather than a requirement.

When it’s all done

20. Make your native extension available to others.

Having completed your extension, you have three choices

  1. Keep it to yourself
  2. Open-source it for other developers
  3. Sell it to other developers

Ask yourself what makes your app unique and special. If it’s not your native extension (and it very rarely is) then choosing option 2 or 3 may have many benefits for you like code contributions from others or additional income.

Further, by making your extension available to other developers you strengthen the ecosystem around Adobe Air as a tool for mobile development. This encourages other developers to use Air and encourages Adobe to continue to develop and improve it. This is in your interests.

At Stick Sports we favour option 2 because we’d rather spend time marketing and supporting our games than marketing and supporting our extensions as commercial products.

17 thoughts on “20 tips for creating Air Native Extensions for iOS

  1. Thanks for suggesting the third option…selling native extensions. I will never (strong word…so maybe a **probably** should be inserted before never…the future is predictably, unpredictable) write my own extension, but really see a need for a robust and thriving native extension ecosystem. I see a strong marketplace which delivers real income as the best way to get there.

    Maybe you could offer your native extensions for commercial licence with forum support, buy the package of extensions for $299 and have the ability to log into the support forum. I am guessing it would be a lot like most endeavors, once you do it a few times, it gets much easier. Maybe you could start a side business just making native extensions?

    I would even like to see Adobe write some native extensions and sell them…who knows…they might make more money doing that than they do selling Flash Builder.

    Oh, and thanks for the detailed article…it may help someone else make some great extensions we can all use sometime down the road.

  2. Great post!Most of the advices are applicable to Android too. I would add few related to Android though, and your article will become the best start place for ANE developer.

    It’s great that you decided to share your experience. I also do that. #20 is my favorite point.

    Btw, I have extended your Flurry ANE to work with Android. More info could be found here. http://lancelotmobile.com/blog/flurry-ane

  3. Thanks for this post!! Really informative and has helped massively building my first native extension.

    I’ve just completed an iOS Bluetooth extension but had one strange problem. The extension works perfectly on the device when compiled with the “ipa-debug-interpreter” target. But when i compile with any other ipa target, the app crashes as soon as a call is made to the extension context?

    I’ve compiled with an apple dev certificate for the app + a self signed certificate for the ane. and followed your build scripts in your game center extension.

    As you seem to be the man for native extensions on t’internet, have you come across this problem before??

  4. Hi Jamie

    I’ve not come across that problem myself, but I know others have. Here’s a brief discussion with some links elsewhere. If you find the solution I’d love to know what it is. Thanks.

  5. I too would be happy to pay for Native Extensions like GameCentre as I don’t know ObjC and want to focus on making my app great, would love to see simpler integration with Flash Builder. Huge thanks for releasing your NE’s to public. Great article!

  6. Pingback: » Native extensions for mobile AIR apps – getting round the orientation issue DiaDraw Blog

  7. Hi, great stuff, but in some of your extensions I’m getting errros when compiling, like for example in the ANE-Can-Open-URL I get:

    [java] ld: unknown option: -ios_version_min
    [java] Compilation failed while executing : ld64

    I’m using the already compiled swc and ANE with AIR 3.2

    Is there any solution for this?, am I doing something wrong?

    Thanks

  8. Hi Alberto

    This will be item 18 above (After seeing your comment I added a little more explanation to the article to make this clearer).

  9. Hello, I’m getting started with Native Extensions, and I just bumped into a problem.
    I have iOS SDK 5.1 in my Mac, but I don’t have the latest iOS version on my old iPod. So everytime I use XCode to compile, I target iOS 4.2.

    Is there a way to do it using ADT?
    Thanks,

  10. HI, recently I’ve tried to do with native extension and with the iBattery example – the first day work with the XCode project did well, it did build successfully even after my small changes (i.e. adding new methods etc.). Next day when I re-visited the same XCode project, I’m starts having an unknown error – “File /Users/webspidersindiapvtltd/Library/Developer/Xcode/DerivedData/AIRExtensionC-dutrbbkegwduvqgbhxkfzjznvrza/Build/Products/Debug-iphoneos/libAIRExtensionC.a depends on itself. This target might include its own product.”

    Really doesn’t have any clue why this suddenly brought in. Any suggestion please (?)

    Thanks.

  11. Pingback: 20???AIR Native Extension???-???????-??????

  12. Hi,

    I’m trying to use your Game Center integration on iOS for my flash project, and I have this error at the end of the publishing :

    “Invalid input.”
    “ld: framework not found GameKit”

    I’ve just added the GameCenter.ane in the publish settings, with the path to the iOS SDK.

    I have the last versions of xcode, and ios sdk.

    Any idea why it’s not working?

    I’m on Mac OSX Lion, using Flash CS6.

    Thank?

  13. Pingback: ANE????????? - ??????????

  14. Pingback: 10 Steps to Learning ANE iOS Development

  15. Pingback: Aymeric Lamboley » AIR ANE

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>