DocsCommand line
App

Command line

Build the app with the takeoff CLI and hand the .ipa to TakeOff, one press from TestFlight.

takeoff archives and exports your app with Xcode, then puts the .ipa into TakeOff. It waits under Ready to upload on the Builds screen, where Upload to TestFlight sends it to Apple with the key TakeOff already keeps. The CLI needs no key of its own and never uploads anything itself.

It builds iOS, tvOS and visionOS apps. Mac apps export as .pkg and are not built by the CLI yet.

Install

zsh
$ npm install -g @takeoff-app/cli
$ takeoff doctor

Install it on the Mac where TakeOff runs, with Xcode, and open your app in TakeOff once so the CLI knows it. takeoff doctor checks Xcode, finds TakeOff’s folder, counts the apps it knows and checks that the terminal can write there. The first time, macOS may ask to let your terminal access data from other apps; allow it.

zsh
$ npm config set prefix ~/.npm-global
$ echo 'export PATH="$HOME/.npm-global/bin:$PATH"' >> ~/.zshrc
$ source ~/.zshrc
$ npm install -g @takeoff-app/cli

takeoff build

Run it in the folder that holds the .xcodeproj or .xcworkspace.

zsh
$ takeoff build --scheme MyApp --build-number auto --app com.example.myapp
  1. Finds TakeOff’s folder first, so a build never runs with nowhere to go.
  2. Archives the scheme with xcodebuild archive, signed automatically.
  3. Exports it for App Store Connect, to disk. The build number stays the one it was built with.
  4. Checks that the bundle ID matches an app in TakeOff and that Apple does not already have that version and build.
  5. Puts the .ipa into TakeOff and brings TakeOff forward.

xcodebuild’s output goes to a log in ~/Library/Caches/takeoff-cli/; when a step fails, its error: lines and the log’s path are shown.

OptionDoes
--path <dir>Folder with the project. Default: the current folder
--workspace <file> · --project <file>What to build. Default: the one in the folder, the workspace first
-s, --scheme <name>Default: the only scheme, or the one named after the project
-c, --configuration <name>Default: Release
--platform <p>ios, tvos or visionos. Default: ios
--team <TEAM_ID>Development team to sign with
-b, --build-number <n>CFBundleVersion. auto takes one more than the highest TakeOff has seen for the app; it needs --app
--version <x.y.z>CFBundleShortVersionString
--export-options <plist>Your own ExportOptions.plist
--app <id>The app in TakeOff, by Apple ID or bundle ID. Default: the one whose bundle ID the build has
--replaceOverwrite the same version and build if it is already waiting
--no-openDo not bring TakeOff forward
--dry-runShow the xcodebuild commands, build nothing
--keepKeep the archive and logs
-v, --verboseShow xcodebuild’s full output
-- NAME=valueBuild settings passed to xcodebuild

takeoff add

Puts an .ipa you already exported into TakeOff, with the same checks as build.

zsh
$ takeoff add ./MyApp.ipa

Options: --app <id>, --replace, --no-open.

takeoff builds

Lists the builds waiting in TakeOff: version, build, app, size and age. --app <id> shows one app’s; --json prints them for scripts.

takeoff remove

Removes a waiting build without uploading it.

zsh
$ takeoff remove 1.0.3 13 --app com.example.myapp

takeoff apps

Lists the apps TakeOff knows on this Mac with their Apple ID and bundle ID — what --app takes.

takeoff doctor

Checks Xcode, TakeOff’s folder and write access to it, and exits with an error when one is missing.

Where builds go

The CLI writes only into TakeOff’s own folder, under Apps/<Apple ID>/builds/<version>/<build>/: the .ipa and a build.json describing it. Each build is assembled in a hidden folder and renamed into place, so TakeOff never lists half a file.