Article

Customizing the Xcode Archive Process

Archive, export, and notarize your app in one step using Xcode post-action build scripts.

Overview

Before distributing your software, you must create an archive containing your executables. From that archive, you must perform additional steps to create a distributable version of your software and to notarize your executables. To simplify the workflow, you can incorporate the distribution and notarization steps into the archive process using post-action scripts.

A post-action script adds custom script commands to the end of standard Xcode commands. To add a script to the Archive command, open the scheme editor for your project and expand the Archive scheme. Select the post-actions option and enter the details of your script in the space provided.

Adding a post-action script to the Archive command in the Xcode scheme editor.

The following sample script exports your archive to a format that can be sent to the Apple notary service. The script includes several calls to the osascript command to display progress messages. Replace the value of the AC_USERNAME and AC_PASSWORD variables with appropriate values for your custom account.

# altool credentials.
# AC_PASSWORD is the name of the keychain item with App Connect password
# Grant access to Xcode if prompted by Xcode.
AC_USERNAME="App Connect Username"
AC_PASSWORD="Keychain Item containing App Connect password"

# Do all of the work in a subdirectory of /tmp, and use a
# unique ID so that there's no collision with previous builds.
EXPORT_UUID=`uuidgen`
EXPORT_PATH="/tmp/$PRODUCT_NAME-$EXPORT_UUID/"
APP_PATH="$EXPORT_PATH/$PRODUCT_NAME.app"
DMG_PATH="$EXPORT_PATH/$PRODUCT_NAME.dmg"

# Xcode doesn't show run script errors in build log.
# Uncomment to save any messages aside.
# exec > "/tmp/Xcode run script.log" 2>&1

# Use osascript(1) to present notification banners; otherwise
# there is no indication of progress until the scripts finish.

/usr/bin/osascript -e 'display notification "Exporting application archive…" with title "Submitting app for notarization"'

# Ask xcodebuild(1) to export the app. Use the export options
# from a previous manual export that used a Developer ID.

/usr/bin/xcodebuild -exportArchive -archivePath "$ARCHIVE_PATH" -exportOptionsPlist "$SRCROOT/ExportOptions.plist" -exportPath "$EXPORT_PATH"

osascript -e 'display notification "Creating UDIF Disk Image…" with title "Submitting app for notarization"'

# Create a UDIF bzip2-compressed disk image.
cd "$EXPORT_PATH/"
mkdir "$PRODUCT_NAME"
mv "$APP_PATH" "$PRODUCT_NAME"

/usr/bin/hdiutil create -srcfolder "$PRODUCT_NAME" -format UDBZ "$DMG_PATH"

osascript -e 'display notification "Submitting UDIF Disk Image for notarization…" with title "Submitting app for notarization"'

# Submit the finished deliverables for notarization. The "--primary-bundle-id" 
# argument is only used for the response email. 
"$DEVELOPER_BIN_DIR/altool" --notarize-app --primary-bundle-id ${PRODUCT_BUNDLE_IDENTIFIER}.dmg -u "$AC_USERNAME" -p "@keychain:$AC_PASSWORD" -f "$DMG_PATH" > "NotarizationUUIDs.log" 2>&1

osascript -e 'display notification "…done!" with title "Submitting app for notarization" sound name "Purr"'

# Open the folder that was created to signal that the script is done.
open "$EXPORT_PATH"