Preparing AdHoc distribution in Titanium Mobile
Tuesday, February 14th, 2012 06:39 pm GMT +2

Appcelerator Titanium is a very promising technology which allows you to write native mobile applications in Javascript for both iPhone & Android.

After playing around a bit with Titanium Mobile, I decided to showcase technology strengths to our stakeholders, particularly by letting them use KitchenSink demo for iOS.

In order to distribute iOS application into real hardware you’ll have to pass through a bunch of  Apple’s obstacles including:

  • Registering as an apple developer & getting valid certificate
  • Registering your app ID
  • Creating provisioning profile for specific iPhone UDIDs
  • Mess around with certificates/private keys to properly sign your application

It turns out that it’s not that easy to produce valid AdHoc distribution of your iOS app in Titanium, in this post I’m going to show you how to do it.


Before we start, make sure you have latest Xcode & Titanium SDK/Studio installed, as of the time of this writing Xcode version was 4.2.1, and Titanium mobile SDK was 1.8.1

For demo purposes we’ll use KitchenSink application provided as a showcase of Titanium mobile:

Clone & run KitchenSink in emulator

git clone

Open Titanium Studio and select File->Import->Import Existing Titanium Project


Configure project for iphone only

KitchenSink configuration

Run project on iOS simulator

KitchenSink on iOS simulator

At this point,  Titanium will create an Xcode project for KitchenSink application. Wait for it to compile and run, then exit Simulator.

Open generated Xcode project

Titanium mobile xcode project

Run Xcode, and open KitchenSink.xcodeproj , Objective-C code could be found at kitchensink/build/iphone

Manage project schemas

In Xcode, open Product->Edit scheme:

Xcode project schema
For each schema (KitchenSink, KitchenSink-iPad, KitchenSink-universal) select Archive and make sure that
Build Configuration is set to debug


Configure code signing for build targets

For each target, select Build Settings -> Code Signing -> Code Signing Identity

code signing configuration for Titanium

Make sure to select valid provisioning identity that you previously created on Apple’s provisioning portal for a particular iOS device/application. In my case, it was called com.nimble.KitchenSink and provisioning profile was called KitchenSink_AdHoc.  For identities to be recognized by Xcode you should have been installed Apple Developer’s certificate as well as your organization certificate into MacOS keychain.

Archive (produce final IPA file)

Select KitchenSink target, then from the main menu choose Product->Archive

Produce IPA file

Wait for Xcode to compile & archive. You may find resulting Archive in Xcode Organizer:

Kitchensink archive

Click “Share” and provide the same identity which was used for Code Signing section above:

IPA provisioning

Save resulting IPA file along with corresponding KitchenSink_Adhoc.mobileprovision   profile.


Install it on device

That’s the easiest part if you’ve done everything right.  Just drag&drop  mobileprovision & ipa  files into iTunes and run sync with an actual iOS device.

If you missed something for code signing, during iTunes sync, you might encounter errors like this:

The executable was signed with invalid entitlements.
The entitlements specified in your application’s Code Signing Entitlements file do not match those specified in your provisioning profile.

  • Jeff

    Or you can do a ‘Install to iOS Device’ from Titanium Studio and you never need to open XCode.  It even prompts you upload the correct provision profiles and installs them into XCode for you.

    • Anonymous

      The scenario you’re mentioning works OK when all you have to do is run app on your own device. When you want to showcase app for other people, meaning that they should be able to install it on their devices — you must tackle Xcode & provisioning stuff. Sadly, Titanium does not provide such functionality out of the box

      • Jeff

        Unless I’m mistaken, you can just copy the .ipa from your build/iPhone folder (after you do a Install to IOS device) for distribution without going into Xcode. I use testflight and just upload my .ipa from my build folder to share it. Does the process you are describing above do something different?

        • Anonymous

          Before you choose “Install to iOS”, Titanium will ask you for dev certificate & provisioning profile for your app. This works OK if you’re using your personal provisioning profile, but the whole process fails if you select AdHoc provisioning profile specifically created to distribute your app for other iOS devices. If you have not experienced those kind of issues, probably testflight does some magic for you behind the scenes

  • Pingback: This Week in Titanium Mobile Development: 20 Feb 2012 | Titanium Development()

  • Tim

    i’m not sure if you can see my reply or not. i follow up your steps exactly as above but now i get a weird problem: all the build / archive / install processes are successful, and i can start my app on my iPad.  BUT the app shows the startup picture and then nothing else (means it shows that picture forever but doesn’t run the real ‘app.js’)?

    attach is my console log in Titanium and the iPad console log. it’s weird that on my iPad the app runs successfully but the console doesn’t have the message ‘[INFO] Application started’ (i can run my app on iOS simulator successfully, through Titanium studio).

    thanks a lot.

    • Anonymous

      Hi!  not sure that I can help you in your iPad case, I have not tried preparing provisioning profiles for iPads, but process should be fairly similar to iPhone.  My suggestion would be to update your Titanium Studio/SDK to the latest available version (this writing was done before version 2.0 came up) and try to reproduce above steps

      p.s. If your app starts and shows startup screen on the device — that’s not a provisioning profile problem, you should debug your app logic to figure out what’s going on

  • Pingback: This Week in Titanium Mobile Development: 20 Feb 2012 | TiDev()