Now that AIR for iOS is back in business, I thought I’d post a quick refresher on how to get the Packager for iPhone working. I tested it yesterday with all kinds of combinations of AIR and iOS versions which have come out since we stopped working on PFI, and everything still works perfectly. It only took me about fifteen minutes to get my environment set up again, and to get iReverse compiled and running on my iPhone 3Gs. (Yes, it might finally be time to upgrade to the iPhone 4.)

If you’re ready to get started developing for iOS devices again, here’s everything you need to know:

1. Download the Packager for iPhone Project

2. Download the Latest AIR SDK

If you’re reading this post, you probably already have the AIR SDK on your development machine, but just in case you don’t, you will need to download the latest AIR SDK (2.0.2) and unpack it.

3. Compile Your Application Into a SWF

Even though the last version of PFI was 2.0.1, and the latest version of the AIR SDK is 2.0.2, they are compatible. Compile your AIR application into a SWF using your favorite method (Flash Professional, Flash Builder, command line tools, etc.). Although it’s not the easiest approach, I use the amxmlc command which is the Flex compiler for AIR applications. The command I run looks something like this (you will obviously need to adapt it to your environment):

4. Use PFI to Build an IPA File

All you need to do now is compile your SWF into an IPA file for your iOS device. Again, you will have to adapt the following command to your specific configuration, but I use something similar to this:

5. Install the Application on Your Device

To install the application on your iPhone, iPod touch, or iPad, simply drag the IPA file into iTunes and sync it with your device. You should see your application icon appear on your device’s home screen.

Epilogue

I recognize that this workflow is far from ideal, especially for developers who use Flash Builder. Keep in mind that what you’re seeing here represents a very low-level usage of the SDKs, and not what we were ultimately planning on releasing. However, we stopped working on PFI before our tools and frameworks could catch up and make the process much simpler.

Moving forward, that won’t be the case. Now that we are once again committed to the iOS platform, we will work on tools and frameworks to make developing iOS applications much easier. I’m currently using early versions of these projects for Android development, and they are extremely easy to use and help to create a very efficient developer workflow. Unfortunately, we’re not going to have these tools and frameworks in place for iOS development overnight, but we will have them, and we will provide developers the easiest, fastest, and most efficient path to writing multi-screen, cross-device applications.

Easy enough. But there’s something to watch out for. Class definitions only get compiled into your SWF if they’re declared somewhere in your code. In other words, if MyClass was never declared, the class definition wouldn’t be included in your SWF, and you would get a runtime error when trying to load it dynamically. (Note that this is not the case for classes native to the runtime — only your own custom classes.) Even importing the class isn’t enough to get it included — it must actually be declared.

There are two ways to work around this issue:

Declare the class somewhere in the code.

Use a command line argument to force the class definition to be included.

Below is an example of declaring the class before loading it dynamically:

This works fine, but in my opinion, it may defeat the purpose of loading a class dynamically. Usually you want to load classes dynamically because you’re not sure until runtime which class you’re going to want. If you knew which classes you wanted before you loaded them dynamically, you could just instantiate them directly.

The other option is to use the mxmlc -includes compiler argument like this:

-includes=com.mydomain.package.MyClass

Now, the class definition will be compiled into your SWF, and you can load it dynamically anytime you want without ever having to declare it.