Introducing EasyIPA

This post is different from the usual struct.ca fare: it’s focused on Flash instead of iOS, and it gets a little technical. Consider yourself warned. :)

Flash to iOS

For the past week I’ve been playing around with the Adobe AIR 2.6 SDK. I used to be a Flash developer and I still really enjoy using AS3, so when Adobe announced a version of AIR with better support for iOS, I had to check it out. It’s pretty impressive, or at least, it’s not awful anymore. You can see an example of it in action here (note that this is NOT something I made, just an example I found):

I tried porting a couple random Flash projects to iOS and they worked well. They didn’t run perfectly, but they ran well enough to say that Flash-to-iOS is actually viable now. (For the record, the iPad doesn’t run Flash stuff nearly as well as the Playbook, but I haven’t had a chance to try it out on an iPad 2 yet.)

The problem

I do my Flash development on Windows (now I’ve really lost everyone ;) ), and one of the issues that frequently comes up while testing Flash-to-iOS apps is the pain of getting IPA files onto my iPhone and iPad. On OSX, it’s easy, you just drag and drop IPA files directly onto the device in Xcode’s Organizer, there’s no need to even bother with iTunes.

On Windows, it’s trickier. You could use iTunes, but its syncing is just way too slow. You could also use Apple’s iPhone Configuration Utility, which is pretty sweet when it works. Unfortunately, I get errors and other weird glitches with it most of the time, but maybe you’ll fare better.

The third option is jailbreaking, which just isn’t worth the hassle, and the fourth is using something like TestFlight or HockeyKit. These tools are awesome when you want to send out ad hoc betas to testers, but it’d be overkill to use them for actual development.

A different way

The way TestFlight works intrigued me, so I decided to do some further investigation. In iOS 4, Apple added the ability to wirelessly download apps directly from your browser, as long the apps are signed and provisioned correctly for your device. This article has all the necessary info on how to do it. You have to create a webpage that links to a plist, and the plist then has links to some icon PNG files and the actual IPA file. There are some caveats, but that’s the gist of it; it’s actually pretty straight forward.

I decided I would create a local web server to host a basic html page and all the required files for wireless app distribution. Think of it like a local version of TestFlight running on your computer. The beauty of it is that it works over wifi, and the IPA gets served directly from wherever it is on your computer, with no uploading required. The issue with most web servers is that they’re usually a bit of work to get running, and I wanted something that was super-lightweight and ridiculously easy to set up, which is how I ended up with good old Adobe AIR.

Over the AIR

Server Sockets are an oft-forgotten feature of Adobe AIR that let you create HTTP servers. This great article by Chrisophe Coenraets is a solid primer on how it’s done. The ability to write a *cross-platform* web server in less than 100 lines of code is pretty powerful.

To get it working all you have to do is start the server and select an IPA file. It even monitors the IPA file for changes using the ideas from this post, so that any time it’s modified, a chime will sound. This is handy because AIR’s IPA packager usually takes a couple minutes, so it’s nice to know when your IPA has been created. I also set it up so that if you keep your device’s browser open, it’ll actually automatically trigger the new IPA to install when it’s been changed.

I use the FZip library to browse through the IPA file (which is really just a zip file), and extact some data from the Info.plist, specifically the bundle identifier, the version number and the app name. These pieces of info only matter while the app is downloading, because after the download finishes, the values in the app’s Info.plist take over.

Once you start the server, all you have to do is navigate to the correct url on your phone (usually something like 192.168.0.10:9999) and you’ll be good to go. Just wait a few seconds or hit the “GET APP” link and the app will download straight to your phone.

Here’s something sneaky: every time you download the app, it appends an incrementing integer to the version number, so that the device always thinks it’s a new build. When the version number says “1.5.1″, it’s actually using “1.5.1.44″, “1.5.1.45″, “1.5.1.46″, etc.

It’s called “EasyIPA”. The magic of AIR means it’ll work on Windows, OSX, and Linux. Just be aware that I didn’t test it very much on OSX (or at all on Linux).

Known issues:

  • On OSX (and probably Linux), you’ll have to manually figure out your machine’s local ip (look in network settings).
  • If you get a “Port #### may be in use” error when starting the server, refresh your device’s browser then restart the server.
  • It can’t extract data from binary Info.plists. This isn’t really a big deal, you’ll just have to enter the info manually (the info doesn’t really matter anyway).

To get it, download and run this.

The AIR runtime should install automatically, but if it doesn’t, get it here.

I threw this together really quickly just as a proof of concept, so the code isn’t very pretty, but if you want to have a look, you can get it here. Feel free to do whatever you want with it.

Please post a comment if you find the app useful or if you run into any issues. Thanks!

UPDATE April 7th: Just made a new version and updated the links above. The only change is that now there’s a field for you to manually specify the server’s IP. This should help in those cases where it can’t figure out your local IP automatically.

This entry was posted in Flash, iOS Development, Workflow. Bookmark the permalink.

35 Responses to Introducing EasyIPA

  1. Troy Gilbert says:

    Awesome. Groovy. Definitely want to play with this…

  2. Rob says:

    Try Beta Tester it creates the webpage for u and it’s open source
    Get it on GitHub

  3. Doug says:

    “On OSX, it’s easy, you just drag and drop IPA files directly onto the device in Xcode’s Organizer, there’s no need to even bother with iTunes.”

    How the hell did I not know this???

  4. Cage says:

    Wonderful gadget, Matt! Really saved my life passing between a Windows and a Mac :)

  5. jhill says:

    After I touch install, I keep getting ‘unable to download’ on the ipad 2. No idea why. Any clue? Here is my log:

    Requesting file at ‘/’
    Returning the file, fileType was html
    Requesting file at ‘/manifest.plist’
    Returning the file, fileType was plist
    Requesting file at ‘/iconNormal.png’
    Returning the file, fileType was png
    Requesting file at ‘/app.ipa’
    Returning the file, fileType was ipa
    Requesting file at ‘/icon512.png’
    Returning the file, fileType was png

    • Matt says:

      Hmm, looks like the iPad is getting the IPA, which makes me think there is something wrong with the actual IPA file. I think it’s probably a provisioning profile issue.

  6. Bruce Flowers says:

    This is great – I got up and running with no issues. I like how it prompts you on the device when it detects a new build. Very well done!

    • Matt says:

      Awesome! :) Glad it worked for you.

      • Bruce Flowers says:

        I spoke too soon – sadly, after about 10-20 successful installs, installation doesn’t work at all any more, not from EasyIPA and not from iTunes. Deleting the app, restarting the device, nothing I’ve tried will work now. I’m working on OS X.

        • Matt says:

          Very strange. The only thing I can think is that you need to increase your apps version number (both in the app, and in EasyIPA). I can’t think of any other reason it wouldn’t work, especially from iTunes. Let me know what type of error you’re getting and I’ll see what I can figure out.

  7. Pingback: AIR Mobile – Déployer des IPA sans iTunes avec EasyIPA (application AIR) - Adobe Flex Tutorial - Tutoriaux Flex Builder, MXML, ActionScript, AS3

  8. Josh Mohan says:

    Hi Matt,

    Looks like a really great tool. I’ve got it so I can reach prompting me to get the .ipa on my desktop browser but my mobile browser times out every time when I navigate to the proper IP/port.

    Any tips would be appreciated! Looks like a real time saver.

    Thanks,

    Josh

    • Matt says:

      Hmm… Is your iPhone/iPad on the same network as the computer? Have you ever run a webserver from that computer and connected to it from your mobile device before? As long as you have the right IP+port, it should be fine…

  9. Josh Mohan says:

    Wow. Yeah, my bad. It was the router on the network I was on while testing this out. Spaced out on that one!

    Great tool, thanks!

  10. George says:

    Really nice job putting this together, sadly it does not work on my iPad (iOs 4.3.3).

    Half way through download i get this message: ‘ “[AppName]” could not be loaded. ‘
    Provisioning Profile is installed and installing the app with iTunes (10.4.0.80) works just fine.

    Any idea what´s going wrong?

    • Matt says:

      Hmm, that’s very strange, I’ve never heard of that error before, I couldn’t even find it in a Google search.

      It could *maybe* be some weird issue with your wifi network, try going to your wifi settings and hitting “Renew Lease”.

      Other than that, I’m not sure, try changing the bundle id and the version number just to see if they have any effect, but they shouldn’t do anything. It’s possible that maybe your version number is lower than the one on the device, that’s the only other thing I can think of.

      Let me know what you find out, I’ll post here again if I find anything.

      • George says:

        The iPad had a german language setting which i changed to english, now it says: ‘ Unable to Download “[AppName]” ‘.
        This gives me some results when put into google.

        Concerning the App Version, i investigated the created manifest.plist and it looks like the replacement of “APP_VERSION” does not seem to work correctly, i got this xml output:
        [...]

        bundle-version
        {{APP_VERSION

        kind
        software
        [...]

        I also tried installing it using ‘ipa-ad-hoc’ and ‘ipa-test’ without success but i really think it fails due to the {{APP_VERSION stuff (tracked it down to lib/emb/txt/manifest.plist – the closing }} are missing).

        • George says:

          I faked the manifest.plist, … on my local Apache and used the correct (ad hoc, distribution) provisioning profile and now it works like a charm :)

        • Matt says:

          Good find!

          I just fixed that bug and replaced the Air file, which you can get here: http://struct.ca/files/easyipa/EasyIPA.air

          It should be version 1.2.4. See if it works for you.

          • George says:

            Nice quick fix, the version issue seems to be resolved, thx!

            … but sadly it´s still not working or me.
            I compared the manifest.plist files and they are identical now (so this seems ok to me).

            My original [myAppName].ipa has a size of 3.14 MB but when i test the download (http://myLocalIP:9999/app.ipa) it actually is returned with a size of only 64.0 KB. I suspect the error is there since it fails while downloading which seems correct to me because the .ipa is way too small.

            I hope this helps !

        • Matt says:

          Hmm, that’s very strange. IPAs are actually zip files, so could you try unzipping it to see what’s contained?

          If the zip file is corrupt, then try renaming the ipa to .txt and see what contents it actually has in it, I feel like there’s definitely something weird going on with it.

  11. George says:

    zip is indeed corrupted but as “txt” it looks like a “usual” binary file to me. Maybe you want to have a look yourself: http://geoathome.at/_stuff/app.ipa

    Today I tested easyIPA on an other pc (Win7 x64) with an other App which was generated using xCode (4) and it worked just fine … *strange*

    • Matt says:

      Strange. Seems like it must have been some weird network issue… maybe even a weird caching problem, either on the iPad or in EasyIPA.

  12. George says:

    As long as it keeps performing on my workstation i am happy :)
    Thank you very much for your time and help with fixing these errors!

  13. Julio says:

    I updated my iphone on ios5 and EasyIPA does’t work. During installation I’m notify that the app can’t be install but I don’t know why.

    • Matt says:

      I haven’t tested it on iOS 5 myself, but I can’t think of any reason it wouldn’t work. Are you able to install the IPA through iTunes or any other way? It sounds like you might have some sort of provisioning profile issue.

      • Amos says:

        Hi Matt,
        I have the same problem with iOS 5.
        Provision is valid – I can sync the app from iTunes, but when I try the same with EasyIPA I get the ‘cannot install’ error.
        My device is iPod Touch 4G running iOS 5.0.1 .

  14. atomi says:

    This is truly a lifesaver for windows development! Great work!

  15. Michael says:

    This looks very nice, thanks. If I can solve my “unable to download”(unrelated to EasyIPA) issue this tool should prove very useful. Thanks.

  16. Nicholas says:

    Super useful tool!!

    Thanks!!

Leave a Reply to Cage Cancel 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>