The following is a walk-through of how to package native iOS applications at the command-line for the purposes of controlling this process through a continuous integration server.
The reason for this is a technology like Sencha and/or Cordova doesn’t give you something which is ready for the AppStore. It gives you an APP file which has to be turned into an IPA file.
Distribution Certificate: A certificate created on the developer portal for distributing one or more applications using one of the following methods: AppStore, Ad Hoc, Enterprise. It is going to be in your Key Chain named something like “iPhone Distribution: AppFoundation (JVD3CHH426)”.
App ID: An application identified that can be used to identify one or more applications. A single application ID would be something like com.foo.MyStupidApp while a multi-application ID would use a wildcard like com.foo.*
Note that if you want to use GameCenter, Push Notifications, or In App Payments to microtransaction your customers to death, you need a single App ID.
Provisioning Profile: This is an App ID specific way of distributing your app, and that is tied to a distribution certificate.
.app file: This is the binary representation of the application, as generated by the sencha native build or what you get when you run the project out of xcode
.IPA file: This is version of the .app file that is signed with a specific distribution certificate and signed with a specific provisioning profile
Release/AppStore: Refers to the IPA file that goes on the AppStore
Ad Hoc: Refers to the IPA file that can be placed on other devices, as long as those devices are manually added to the related iOS developer account.
Enterprise: Refers to the IPA file that can be distributed internally (like through Test Flight or your own AppStore), without having to manually specify and connect devices to the iOS developer account.
Before you do anything of this, you have to make sure that you have the latest Xcode command line tools.
Xcode -> Preferences -> Downloads
Select “Command Line Tools”
The issue was that without this magic you are missing the application: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/codesign_allocate
This shows on the Apple developer portal at Certificates -> Production as an entry for “Your Name” of type “iOS Distribution”
If it doesn’t show here, you have to create it.
Select “AppStore and Ad Hoc”
Follow the instructions to create a CSR file
Download the generated certificate
Double-click on it to import it into you keychain
To do this you need to pay for the Enterprise account (299/year), where you then have to sign in to that account and do these steps:
Select “In-house and Ad Hoc”
Follow the instructions to create a CSR file
Download the generated certificate
Double-click on it to import it into your keychain
From the Apple developer portal website:
Identifiers -> App ID -> Create New
Select “Wildcard App ID”
Enter something like com.appfoundation.*
What gets generated is something like the following: JVD3CHH426.com.appfoundation.*
You now see this listed under Identifiers -> App IDs as:
Name:
AppFoundation General
Prefix:
JVD3CHH426
ID:
com.appfoundation.*
From the Apple developer portal website logged in with the Enterprise Account:
Identifiers -> App ID -> Create New
Select “Wildcard App ID”
Enter something like com.appfoundation.*
What gets generated is something like the following: WDS3CHH426.com.appfoundation.*
You now see this listed under Identifiers -> App IDs as:
Name:
AppFoundation General
Prefix:
WDS3CHH426
ID:
com.appfoundation.*
From the Apple developer portal:
Provisioning Profiles -> Distribution -> Add
Select AppStore fromt the list of the following: Dev, Ad Hoc, or AppStore (I assume if you pay for enterprise it is here as well)
You then have to select the App ID you created above, for example com.appdoundation.*
You then have to select an existing distribution certificate, which means you already need to have followed the process from “Create a Production Distribution Certificate (Release and Ad Hoc)”
Specify a profile name in the following format: iOS Distribution AppFoundation (JVD3CHH426)
Download the file on the screen which will be in the format of iOS_Distribution_AppFoundation_JVD3CHH426.mobileprovision
Double-click on it, which will magically add it to your login keychain and create a file in /Users/YOUR_USER_NAME/Library/MobileDevice/Provisioning Profiles
Which file it is, I don’t know. You will have to look at the date to determine that. The file will look like this: C38394F4-E43E-4B4D-860A-493D15FCEE05.mobileprovision
Note that you cannot have an Ad Hoc Distribution profile without at least 1 device.
To Add a device you have to do the following:
Devices -> Add
Note that you have to add devices in groups, if you have to add a new device you have to re-add all devices, again
You can get the UUID out of test flight by going to People -> Clicking on the “I” icon next to the name
Also note that you have to regenerate the Ad Hoc Distribution Profile every time you change devices
From the Apple developer portal:
Provisioning Profiles -> Distribution -> Add
Select Ad Hoc fromt the list of the following: Dev, Ad Hoc, or AppStore
You then have to select the App ID you created above, for example com.appfoundation.*
You then have to select an existing distribution certificate, which means you already need to have followed the process from “Create a Production Distribution Certificate (Release and Ad Hoc)”
You now have to select the specific devices that you want to push to.
Specify a profile name in the following format: iOS Ad Hoc Distribution AppFoundation (JVD3CHH426)
Download the file on the screen which will be in the format of iOS_Ad_Hoc_Distribution_AppFoundation_JVD3CHH426.mobileprovision
Double-click on it, which will magically add it to your login keychain and create a file in /Users/YOUR_USER_NAME/Library/MobileDevice/Provisioning Profiles
Which file it is, I don’t know. You will have to look at the date to determine that. The file will look like this: 594F9DF1-0F3F-45B2-AA23-C3A207236EC7.mobileprovision
Do the following when signed is to the enterprise account from the portal:
Provisioning Profiles -> Distribution -> Add
Select In House fromt the list of the following: Ad Hoc or In-House
You then have to select the App ID you created above, for example com.appfoundation.*
You then have to select an existing distribution certificate, which means you already need to have followed the process from “Create a Enterprise Distribution Certificate”
Specify a profile name in the following format: iOS Enterprise Distribution AppFoundation (WDS3CHH426)
Download the file on the screen which will be in the format of iOS_Enterprise_Distribution_AppFoundation_WDS3CHH426.mobileprovision
Double-click on it, which will magically add it to your login keychain and create a file in /Users/YOUR_USER_NAME/Library/MobileDevice/Provisioning Profiles
Which file it is, I don’t know. You will have to look at the date to determine that. The file will look like this: 594F9DF1-0F3F-45B2-AA23-C3A207236EC7.mobileprovision
The following is a script that can correctly build a .APP and use it to create Release, Ad Hoc,and Enterprise IPA files signed with the appropriate certificate.
#!/bin/bash
# You have to externally set these environment variables:
# SYS_BUILD=1
# BUILD_DIR=.
# APP_NAME=SomeAppName
# ENVIRONMENT=test
# NAME_PREFIX=app-name
# APP_ID=com.appfoundation.SomeAppId
# You have to do this to correctly sign the .app
export CODESIGN_ALLOCATE="/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/codesign_allocate"
# This is the name of the certificate you want to use as listed in your keychain.
# This will either be for Release/Ad Hoc or Enterprise
export SIGNING_IDENTITY="iPhone Distribution: AppFoundation (JVD3CHH426)"
# This is the full path to the provisioning profile you are doing to use
# This will either be Release, Ad Hoc, of Enterprise
export PROVISIONING_PROFILE="${HOME}/Library/MobileDevice/Provisioning Profiles/C38394F4-E43E-4B4D-860A-493D15FCEE05.mobileprovision"
# This is just the GUID from the above provisioning profile
export PROVISIONING_GUID="C38394F4-E43E-4B4D-860A-493D15FCEE05"
# Unlock the keychain using our account on your mac
security unlock-keychain -p "YOUR_PASSWORD" ~/Library/Keychains/login.keychain
# Set the version of the application being built
/usr/bin/agvtool new-version -all ${SYS_BUILD}
/usr/bin/agvtool new-marketing-version ${APP_VERSION}
# Build a Universal app for either Release, Ad Hoc, or Enterprise depending on what you specified above
xcodebuild -alltargets -sdk iphoneos -configuration Release clean build \
CONFIGURATION_BUILD_DIR="build" \
PROVISIONING_PROFILE="${PROVISIONING_GUID}" \
CODE_SIGN_IDENTITY="${SIGNING_IDENTITY}" \
TARGETED_DEVICE_FAMILY="1,2"
# Create an IPA of the current APP for either Release, Ad Hoc, or Enterprise
xcrun -sdk iphoneos PackageApplication -v "build/${APP_NAME}.app" -o \
"${BUILD_DIR}/cordova/platforms/ios/${NAME_PREFIX}-ios-${ENVIRONMENT}-${SYS_BUILD}.ipa" \
--sign "${SIGNING_IDENTITY}" \
--embed "${PROVISIONING_PROFILE}"