The secrets of Compress vs Winzip when packing your iPhone App

Beta Testing Disaster: “It Crashed”

I smiled as the AdHoc version of my new iPhone game zipped through the intertubes, neatly delivering itself to each beta tester to enjoy with his cheese and wine.  What could go wrong, my code is perfect as always.  (Yeah…)

My smirk turned to horror as the replies came in – two of my ten testers reported that the game instantly crashed after the splash screen.

Using logic, reason, and Jetro to figure it out

Would this happen in real distribution? Can I really release a game that crashes on 20% of devices?  Not on my watch, not at RTsoft! (19% is our cut-off point)

They both happened to be 3GS devices.  A divide by zero that only happens with the faster processor?  Why didn’t the other two 3GS testers crash?  Related to being jailbroken?  iPhone OS version?

Nope, none of the above.

  • The first big clue was when we noticed that no crash log was created – this made it likely that the app wasn’t even starting.  (The splash screen is actually shown by the OS while the real game loads)
  • The second clue was when we noticed that only those using iTunes on the mac had the problem.  Forgot to ask about OS when signing up testers…
  • I would have to say the biggest clue was when Jetro figured it out and told me what the problem was.  Yeah, that helped.

It’s the packaging, dummy

I’m a windows guy.  I test, debug,  package and ftp my stuff in Windows.  I use .bat file scripts for frakin’ everything.

This is A Bad Thing when packing iPhone stuff.

Actually I made two mistakes.  And yeah, they are both explicitly warned against in the iPhone developer documentation so I really have no excuse here.

Mistake 1: Letting XCode use a networked Windows drive to build on

I was using a windows network drive for my build directory.  It has the unfortunate side effect of losing some permission data and just setting everything to +x (executable).

xcode_build

Interesting fact though, despite the strange attributes, you CAN use OS X’s Compress and create a working AdHoc and even final distribution build from a build on a networked Windows drive.  I know, because Apple accepted Dungeon Scroll…  However, looking at this, I won’t do that again.

Mistake 2: Zipping from Windows using 7zip or Winzip

The rules of iPhone zip packing:

  • Zipping from Windows using Winzip or 7zip does NOT store special os x/linux file attributes/permissions, and that is Not A Good Thing.
  • Using “Compress” on the Mac does it right.  I mean hey, all those weird junk files OS X adds had to be good for something, right?

When unzipped and installed through iTunes on OS X, everything installs ok, but when you run the game on  the device it notices the game binary doesn’t have the +x execution attribute set and fails. 

Note: In a bind, you can fix this by using chmod on it manually before you install.  Could save you if you are a beta tester who has to deal with this problem and can’t get hold of the developer.

Zipping on the mac from shell script

So the next question of course is “Fine, I’ll use the damn mac, but how can I automate this?”

command_icon

Pretty easy.  Here is how to make an icon that will make the zip and add your adhoc .mobileprovision. (This would only be for sending to testers)

  • Create a text file and name it build.command
  • Insert the script pasted below, customized it for what you need
  • Drop to the command prompt and do: chmod +x build.command
  • From Finder, find the file, right click and choose Make Alias
  • Drag the alias to your desktop

Now you can click the icon and have your zip made and copied somewhere for you!

I’ll leave it to you to figure out how to also have it do the xcode building and ftp it somewhere.

Here is the simple script to zip it up:  (It uses ditto for the zipping.. which I should really verify is going to work with everything, but hey, Trust Me)

Code:

#!/bin/bash
echo Zip .app with the mobileprovision for beta testers

#App name is the MyGame.app without the app part, that will be added
APPNAME=RT4Player

OUTPUTZIPNAME=${APPNAME}AdHoc.zip

#buildir is the root build directory as set in xcode
BUILDDIR=~/build

#mobile provision to include for the beta testers to add using itunes
MOBILEPROVISIONFILE=/Volumes/projects/iphone/AppleStuff/RTAdHoc.mobileprovision

#make a temp dir to put our files in first, as ditto can't seem to add files to an existing zip
mkdir $BUILDDIR/temp

#copy the files want to zip there
ditto $BUILDDIR/AddHoc-iphoneos/$APPNAME.app $BUILDDIR/temp/${APPNAME}.app
cp $MOBILEPROVISIONFILE $BUILDDIR/temp

#actually make the zip
ditto -c -k $BUILDDIR/temp $BUILDDIR/${OUTPUTZIPNAME}
rm -rf $BUILDDIR/temp/

#copy it over to our windows drive, as that's where my .bat files will rename it and ftp it
cp $BUILDDIR/${OUTPUTZIPNAME} /Volumes/projects/iphone/$APPNAME

Leave a Reply

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