iOS5 support for AIR/Using external SDKs to package apps

AIR 3.1 introduces significant improvements to the way native extensions can be used on iOS. Firstly, it lets you package your apps with an external SDK so that you are not restricted to using the captive SDK. If you have built an extension with the latest iOS SDK to access the latest features you can now specify that SDK when packaging the app. You can specify an iOS sdk to link with using the -platformsdk switch when packaging an IPA. Simply add -plaformsdk /path/to/iPhoneOS5.0.sdk to your regular commandline for packaging the ipa. The complete command line will look like this:

adt -package -target ipa-app-store -provisioning-profile ./myProfile.mobileprovision -storetype pkcs12 -keystore ./Certificates.p12 -storepass XXX myApp.ipa myApp-app.xml Main.swf -extdir ext/ -platformsdk /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk/

 

The -platformsdk switch is supported both on Mac and on Windows. The packager will not attempt to validate the SDK being used to create the IPA. Any errors encountered when packaging the IPA will be reported back to you.

The packager, of course, does not know anything about the frameworks and the libraries available in the iOS SDK and you would have to specify any dependencies on them explicitly. This is where the second enhancement comes in: Starting AIR 3.1 you can specify dependencies on frameworks or shared libraries as well as other linker options when creating your ANE. The linker picks up these options when linking your extension to the runtime. The runtime links with the following frameworks for extension namespace version 3.1 by default:

  • CoreFoundation
  • UIKit
  • MobileCoreServices
  • CoreGraphics
  • SystemConfiguration
  • AudioToolbox
  • CFNetwork
  • QuartzCore
  • CoreLocation
  • CoreMedia
  • CoreVideo
  • AVFoundation
  • Foundation
  • OpenGLES
  • Security

If your extension uses any other frameworks or any shared library you will have to specify the dependency explicitly. If you specify an external SDK when packaging the IPA, the packager will look in the System/Library/Frameworks and the usr/lib subdirectories of the sdk for the frameworks and the shared libraries respectively by default. You can specify additional search directories in the descriptor file. These paths should be relative to the sdk root. If the captive sdk is used to package the IPA, the frameworks listed in the descriptor file will be picked from within the AIR SDK directory and the search paths specified in the file will be ignored. You will have to add these dependencies and any other linker options  to a platform specific descriptor file. The platform specific options file will have to be specified when packaging the ANE using the new -platformoptions switch. A options file might look like this:

<platform xmlns="http://ns.adobe.com/air/extension/3.1">
    <sdkVersion>5.0</sdkVersion>
    <linkerOptions>
	    <!-- to use the Twitter framework -->
        <option>-framework Twitter</option>
		<!-- to link with the libiconv.dylib -->
        <option>-liconv</option>
    </linkerOptions>
</platform>

And a command line to create an ANE with the platform options might look like this:

adt -package -target ane myextension.ane extension.xml -swc mySwc.swc -platform iPhone-ARM library.swf libmylib.a -platformoptions myplatformoptions.xml

 

Till AIR 3.0, you could only use frameworks which were shipped with the AIR SDK. As the packager did not provide the extension developer any way of specifying dependencies of the native code on other binaries, it linked in all available frameworks. Since the minimum supported version of the SDK for AIR 3.0 was 4.0, it only linked in frameworks available in iOS SDK version 4.0.  The runtime will maintain this behaviour for extension namespace version 2.5 to maintain backward compatibility.

Yet another enhancement is the facility to specify custom entitlements for your application. If your extension needs special entitlements to run you can specify those entitlements in the iPhone specific section of the application descriptor as follows:

<iPhone>
	<!-- A list of plist key/value pairs to be added to the application Info.plist -->
	<InfoAdditions>
            <![CDATA[
                ...
            ]]>
        </InfoAdditions>
        <!-- A list of plist key/value pairs to be added to the application entitlements -->
        <Entitlements>
            <![CDATA[
                <key>keychain-access-groups</key>
                <array>
                    <string>...</string>
                    ...
                </array>
                ...
            ]]>
        </Entitlements>
</iPhone>

To find out how to add custom entitlements to applications when using older versions of the AIR SDK see my older post.

Update: -platformsdk switch is now supported on Windows since AIR 3.5. When using the iOS SDK on Windows, be sure to extract it using a reliable DMG extractor tool which preserves symbolic links. Else you might encounter linker errors.