There are a number of tutorials out there on the Internet that tell you how to do Sencha Touch native packaging for iOS. The subject is also covered pretty well in the Sencha Touch docs. The problem I have with all those resources: they’re either outdated, outright wrong or stop half-way.
I don’t need a tutorial whose title claims to describe how to create an .ipa file and then simply describes how to produce an .app file – something that’s much better explained in the Sencha docs. Also, those tutorials that tell you how to produce a binary for your own single device stop half-way. Why? Because I expect you usually want to have a more or less convenient setup for all your own and your beta-testers devices, don’t you?
So, let’s cut to the chase. I’ll show you how, based on a regular Sencha Touch project, you can:
- create an iOS binary
- use an Apple provision profile for all test devices
- wrap that into an .ipa package which can then be
- upload to your website which does
- provide a convenient download link
- automate the whole process
Hint: it’s easier to build an iOS binary on a Mac!
Given is a standard Sencha Touch project that was created e.g. using the Sencha Cmd tool. Note that if you’re using Sencha’s rapid prototyping tool Sencha Architect things may be different. See the Sencha docs for details but essentially what you need to do:
- download and install Sencha Cmd
- download Sencha Touch and unpack it somewhere on your machine
- open the console
- change to the Sencha Touch directory (see 2.)
sencha generate app <app-name> <path-where-to-store-generated-app>
You get a directory structure like this
First and foremost, you need to be a member of the iOS Developer Program ($99/y)!
Once you signed up you should carefully read the Sencha docs on native provisioning. Take your time, it can be quite confusing and be prepared to also read some of the Apple docs that are referenced in the Sencha docs.
What you need to not only test the app on your own device but on those of your beta-testers is a so called ad hoc provisioning profile. It’s a container for
- the app ID
- the list of registered device UDIDs (up to 100)
- the iOS Distribution certificate
The three items listed above are the ingredients you need to create a distribution profile. As I said, go through the docs referenced above and you’ll get there.
Before you proceed you need to make sure you have an
<app-name>.mobileprovision file in the Sencha project folder and the distribution certificate in your OS X key chain.
When Sencha Cmd created your initial project it included a file called packager.json. In contains all the configuration parameters for the native build. In version 2.3 of the docs there’s now a nice overview of which parameter is used for which platform. Some are only for iOS others are only for Android and some are shared. Eventhough some values are shared I prefer to keep one file for each platform (
Despite the good documentation there are three things I’d like to point out based on my current iOS packager config:
/* iOS icon docs: http://goo.gl/yTIsa8 */
"certificateAlias": "iPhone Distribution: my name (some-Apple-ID)",
"icon"If you us an app-icon-generator service such as makeappicon.com you get a specific icon for each device/resolution combination. Thanks to iOS 7 we just got a bunch of additional icon sizes that an app is expected to support. You see that I listed an icon for each of the currently supported dimensions. However, Sencha native build currently only considers 57/114 & 72/144. I already reported that.
"outputPath"You’ll get an explanation for the potentially odd-looking path in the next chapter.
"configuration"Contrary to what the current Sencha documentation says the value has to be Release instead of Debug for ad hoc distributions. That’s a bug in the docs that I reported.
From .app to .ipa
At this point you should be able to run
sencha app package build packager-ios.json on the console in the project’s root directory. This produces a folder called <app-name>.app in the defined output folder (see packager.json). In the OS X Finder this appears as a single file but you can peek at the content by right-clicking it and selecting ‘Show Package Contents’.
Now you may hook your iOS device up to your Mac, start iTunes, and drag the .app file from Finder to the device in iTunes. Next time the device is synced the app is installed. That may be good enough for yourself – for the first installation. For anything else that’s too cumbersome.
So, the next step is to package the
.app file into an
.ipa file (if not obvious see next chapter why). Since an
.ipa is nothing more than a ZIP file with a different file ending that’s fairly easy. However, the
.app in the
.ipa has to reside in a
/Payload subfolder. Remember the configuration of my output folder in the packager.json? Simply zip the entire
/Payload folder to file called
<app-name>.ipa and you’re nearly home free…
Wireless ad hoc distribution
Getting your latest and greatest version out to the beta testers and all your own devices is important. It should be a hassle-free one-click experience for those installing your app. Enter, wireless ad hoc distribution. I’m going to show you how to build a web page with a hyperlink which when clicked in an iOS Safari browser downloads and installs the app on the device.
- an HTML page
.ipafile from the previous step
- an Apple
First, upload the
.ipa to a web server. You may want to include the version in the file name.
Second, use the below
.plist template, adjust the values, and save it as
<app-name><version>.plist. Upload it to the same folder on the web server as the
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
Note that the string on line 14 needs to be the fully qualified URL to the
.ipa to download! The string on line 26 is the name of app as it will be labeled on the iOS home screen.
Third, use the below HTML template, adjust the value of the hyperlink URL and save it on the web server, too.
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
Again, the URL on line 9 must be fully qualified
Tip I: read the Apple documentation on wireless distribution if you get stuck.
Tip II: if you want to outsource app distribution and get a boatload full of cool extra features I recommend you give TestFlight a try.
Puhh, lots can go wrong in the numerous steps it takes to get here. And if it can it probably will, sorry. The good thing though is that once all the configuration is in place it’s easy to run the whole process over and over again. However, as everything that’s repetitive and mechanical it should be done by machines rather than by humans.
So, in theory all you need is a script that triggers the Sencha Touch native packaging for iOS and uploads the produces artifact to the web server. Shortcomings of Sencha Cmd, however, require that a few extra steps should be built into the script. See, by default Sencha Cmd includes everything in your project folder in the final binary – even superfluous artifacts. Entire Git repository in the
.git folder? Packaged into the
.app. The build folder containing local Sencha app builds? Packaged into the
.app. Your IDE’s project config files? Also packaged into the
.app. If this wasn’t addressed your native package would contain 70-90% waste.
So, in practice the script first copies all relevant files and folders to a temporary build folder. Sencha Touch native packaging for iOS is then triggered from there.
echo Clearing build dir $BUILD_DIR...
rm -fr $BUILD_DIR
echo Creating artifacts dir $ARTIFACTS_DIR...
mkdir -p $ARTIFACTS_DIR
mkdir -p $ARTIFACTS_DIR/.sencha
echo Copying content of current dir to artifacts dir...
cp -R * $ARTIFACTS_DIR
cp -R .sencha/* $ARTIFACTS_DIR/.sencha
echo Changing into artifacts dir...
echo Invoking Sencha native build in current directory...
sencha app package build packager-ios.json
echo Changing into dist dir...
echo Wrapping newly built .app into .ipa...
zip -r -q $IPA_FILE zipfile Payload
echo Uploading .ipa to FTP server...
curl -T $IPA_FILE -u user:password --ftp-ssl -k ftp://www.senchatest.com/public_html/adhoc/
Save this file as
deploy-ad-hoc.sh or so in the root of the Sencha project, add execute permissions, and run it from there. There’s help creating shell scripts, too.
Conclusion: Sencha Touch native packaging for iOS done right!
I hope I could prove to you that it is possible to do Sencha Touch native packaging for iOS right. It took me a few hours but will save me countless hours in the future. It works quite well for me.
At the moment I only see one improvement that bugs me enough that I’ll address it sooner or later. The version is currently hard coded into two configuration files (packager.json, .plist) plus the HTML page and the deploy script. Furthermore, whenever I switch to a new version I need to upload the .plist to the server manually.
P.S. after I was done I discovered http://gknops.github.io/adHocGenerate/ which offers pretty good guidelines, too.