Tuesday, April 16, 2013

Gotcha of the Day: Adobe AIR's ipa-app-store packaging produces a corrupt IPA file

A few weeks back I got a request from one of my clients to generate an iOS version of their app for use on the iPhone and iPad. No problem, I figured, as I built the original app using Adobe AIR. I figured I'd need to issue a new adt command and I'd be all set. OK, the process wasn't exactly that easy; I needed to generate a provisioning file, a certificate and jump through half a dozen other hoops on developer.apple.com, but in the end, I did indeed get the app to be packaged.

There are a number of packaging targets available, including: ipa-test, ipa-app-store and ipa-test-interpreter.

I was in test mode, so I figured I'd try ipa-test. The result was an application that would install on my iPad, yet when executed would bring up a black screen and hang there. Looking for other options I tried using ipa-test-interpreter. Whoo! This option worked perfectly on my iPad. I was able to compile, install and debug my app on iOS. I was happy.

Then it came time to submit my App to Apple. I packaged up the app using ipa-app-store and sent it on over. Within a day or two I got back a rejection notice, the app didn't start up (whoops!). In testing when I tried ipa-app-store I got the Black Screen of Death, but I just assumed that was because mere mortals weren't supposed to try to execute app-store files. This logic was totally wrong.

I fiddled with everything I could. I removed the native extension I was using. I simplified the program. No matter what I did, -target ipa-test-interpreter worked great and -target ipa-app-store resulted in an IPA that brought up a black screen and died.

Finally I reached out to Adobe support. For what seemed like weeks we went around and around on this issue. I'd explain the issue, they came back and explained it was a packing and provisioning problem. I explained that it worked fine when built using -target ipa-test-interpreter and so it couldn't be a provisioning problem. Every communication we had seemed to start of with me re-explaining the problem.

Finally, at Adobe's Request, I tried using Flash Builder instead of the low level adt commands. It worked! I proved that I could somehow produce a ipa-app-store file that functioned. But I didn't want to use Flash Builder, I wanted to use my finely crafted Makefile which utilized adt.bat.

After my Flash Builder success, the Adobe technician had me try building this example using command line tools. Again, to my shock, it worked just fine.

Looking at the example provided I realized that I was using mxml / Flex code, whereas the working code was pure ActionScript. Maybe that was the problem? I started rewriting my app in pure ActionScript. Still, when I packaged my app using ipa-app-store it failed to run. Another dead end.

Finally, I noticed a difference in the way I was building my project and the way the demo from Adobe was built. Here was my command line:

adt.bat -package -target ipa-app-store \
        -keystore cert.p12 \
        -storetype pkcs12 -storepass XXXXXXXXXXXX \
        -provisioning-profile HelloWorld.mobileprovision \
        HelloWorld.ipa HelloWorld-app.xml src/HelloWorld.swf \
        -C src icons 

And here was the version provided by the Adobe technical support rep:

adt.bat -package -target ipa-app-store \
        -keystore cert.p12 \
        -storetype pkcs12 -storepass XXXXXXXXXXXX \
        -provisioning-profile HelloWorld.mobileprovision \
        HelloWorld.ipa HelloWorld-app.xml HelloWorld.swf \

The difference? In my attempt to organize my source code I stored the HelloWorld.swf in a sub directory named src and I utilized -C to have adt properly pick it up.

To my utter amazement, if I reorganized my source code so the -C option wasn't required, it built a perfectly valid ipa-app-store IPA file. This just about blew my mind: my complex app was failing, and it was doing so all because -C was utilized in the command line arguments of the packager.

I've checked and rechecked this a number of times. I usually invoke adt.bat from Cygwin, but have gotten the exact same results with cmd.exe. I've installed the latest version of Flex and AIR and confirmed the problem.

Unfortunately, the Adobe Support Rep isn't able to recreate the issue on his side. He did say, however, he would dig into and see what he could learn.

Me, I'm happy. A few days ago I submitted a version of the app to the App Store and today it was accepted.

1 comment:

  1. Thank you so much for this work around, I've been looking for a fix everywhere, couldn't find where I was doing wrong. It was just the directory of the swf bin/XXXXXX.swf => direct access ... Seriously...

    I've been using air3.4 till then, it's handling this fine however all the next versions halted on splash screen without being able to trace anything...
    Thank you Ben !