Skip to content

Instantly share code, notes, and snippets.

@powerc9000
Created July 19, 2016 06:10
Show Gist options
  • Star 17 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save powerc9000/7a339fca691f86ae526e68a8b80790b5 to your computer and use it in GitHub Desktop.
Save powerc9000/7a339fca691f86ae526e68a8b80790b5 to your computer and use it in GitHub Desktop.
Creating and uploading iOS archives from the command line.

I don't like IDEs. I want to code in my editor and use the command line for everything else. I like the flow better and it feels faster to me.

I also like to have one command to do several things I want to do.

I don't want to open Xcode to create an archive, then open the archive window, then upload the archive to iTunes. It's slow and breaks my flow.

Also, in react native, it's trivial to build Android releases on the command line. I want to create and upload both iOS and android from the command line.

So after hours of searching the internet I found a flow I like for creating and uploading archives for iOS all from the command line

Creating the archive

xcodebuild archive -scheme <scheme-name> -project <your-project>.xcodeproj -configuration <Relase|Debug|Test> -archivePath <where-you-want-to-save-your-archive> && 
xcodebuild -exportArchive -archivePath <where-you-saved-the-archive> -exportPath <ipa-output>.ipa -exportFormat ipa -exportProvisioningProfile <your-provisioning-profile-name>

This should create an ipa in whatever path you specified with -exportPath

Uploading the archive

#!/bin/bash
#set -ex

# This scripts allows you to upload a binary to the iTunes Connect Store and do it for a specific app_id
# Because when you have multiple apps in status for download, xcodebuild upload will complain that multiple apps are in wait status

# Requires application loader to be installed
# See https://developer.apple.com/library/ios/documentation/LanguagesUtilities/Conceptual/iTunesConnect_Guide/Chapters/SubmittingTheApp.html
# Itunes Connect username & password
# I store my username and password in a seprate file outside the repo. With the format `username password`
USER=$(awk 'BEGIN {FS=" "}; {print $1}' ../keys/itunes)
PASS=$(awk 'BEGIN {FS=" "}; {print $2}' ../keys/itunes)

# App id as in itunes store create, not in your developeßr account
APP_ID='<your-app-id>'


IPA_FILE=$1
IPA_FILENAME=$(basename $IPA_FILE)
MD5=$(md5 -q $IPA_FILE)
BYTESIZE=$(stat -f "%z" $IPA_FILE)

TEMPDIR=temp
# Remove previous temp
test -d ${TEMPDIR} && rm -rf ${TEMPDIR}
mkdir ${TEMPDIR}
mkdir ${TEMPDIR}/mybundle.itmsp

# You can see this debug info when you manually do an app upload with the Application Loader
# It's when you click activity

cat <<EOM > ${TEMPDIR}/mybundle.itmsp/metadata.xml
<?xml version="1.0" encoding="UTF-8"?>
<package version="software4.7" xmlns="http://apple.com/itunes/importer">
    <software_assets apple_id="$APP_ID">
        <asset type="bundle">
            <data_file>
                <file_name>$IPA_FILENAME</file_name>
                <checksum type="md5">$MD5</checksum>
                <size>$BYTESIZE</size>
            </data_file>
        </asset>
    </software_assets>
</package>
EOM

cp ${IPA_FILE} $TEMPDIR/mybundle.itmsp

/Applications/Xcode.app/Contents/Applications/Application\ Loader.app/Contents/itms/bin/iTMSTransporter -m upload -f ${TEMPDIR} -u "$USER" -p "$PASS" -v detailed

test -d ${TEMPDIR} && rm -rf ${TEMPDIR}

Usage: ./itunes_upload.sh <path-to-ipa>

With this setup you never have to touch xcode to build and upload your iOS archives.

What's great about this is, as long as you have your build setup you can use this for any iOS project you create.

@jhbertra
Copy link

Followed this gist, got xcodebuild: error: invalid option '-exportFormat'

@powerc9000
Copy link
Author

Followed this gist, got xcodebuild: error: invalid option '-exportFormat'

I couldn't say. I haven't touched this in 3 years and xcode could certainly have changed especially with the 32 -> 64 bit change

@mattslight
Copy link

@jhbertra try react-native run-ios --configuration Release

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment