XCode "Build and Archive" из командной строки - PullRequest
375 голосов
/ 19 апреля 2010

Xcode 3.2 предоставляет потрясающую новую функцию в меню Build, «Build and Archive», которая генерирует файл .ipa, подходящий для Ad Hoc распространения. Вы также можете открыть Органайзер, перейти к разделу «Архивные приложения» и «Отправить приложение в iTunesConnect».

Есть ли способ использовать «Build and Archive» из командной строки (как часть сценария сборки)? Я бы предположил, что xcodebuild будет каким-то образом вовлечено, но страница man, похоже, ничего об этом не говорит.

ОБНОВЛЕНИЕ Михаил Гринич запросил разъяснения; вот что именно вы не можете сделать с помощью сборок из командной строки, функции, которые вы можете сделать ТОЛЬКО с Xcode Organizer после «Сборка и архивирование».

  1. Вы можете нажать «Поделиться приложением ...», чтобы поделиться своим IPA с бета-тестерами. Как указывает Гийом ниже, из-за некоторой магии XCode этот файл IPA не требует отдельно распространяемого файла .mobileprovision, который требуется установить бета-тестерам; это волшебно Никакой сценарий командной строки не может это сделать. Например, сценарий Arrix (представленный 1 мая) не соответствует этому требованию.
  2. Что еще более важно, после того, как вы протестировали сборку, вы можете нажать «Отправить приложение в iTunes Connect», чтобы отправить эту ТОЧНУЮ сборку в Apple, сам бинарный файл, который вы тестировали, без перекомпоновки. Это невозможно из командной строки, потому что подписание приложения является частью процесса сборки; вы можете подписывать биты для бета-тестирования Ad Hoc ИЛИ вы можете подписывать их для отправки в App Store, но не для обоих. Ни один IPA, построенный на командной строке, не может быть бета-тестирован на телефонах, а затем отправлен непосредственно в Apple.

Я бы хотел, чтобы кто-то пришел и доказал, что я не прав: обе эти функции прекрасно работают в графическом интерфейсе XCode и не могут быть реплицированы из командной строки.

Ответы [ 19 ]

309 голосов
/ 16 ноября 2010

Я нашел, как автоматизировать процесс сборки и архивирования из командной строки, я только что написал статью в блоге , объясняющую, как этого добиться.

Вы должны использовать команду xcrun:

/usr/bin/xcrun -sdk iphoneos PackageApplication \
-v "${RELEASE_BUILDDIR}/${APPLICATION_NAME}.app" \
-o "${BUILD_HISTORY_DIR}/${APPLICATION_NAME}.ipa" \
--sign "${DEVELOPER_NAME}" \
--embed "${PROVISONING_PROFILE}"

Все подробности вы найдете в статье . Если у вас есть какие-либо вопросы, не стесняйтесь спрашивать.

275 голосов
/ 27 октября 2011

С Xcode 4.2 вы можете использовать флаг -scheme, чтобы сделать это:

xcodebuild -scheme <SchemeName> archive

После этой команды Архив появится в Xcode Organizer.

127 голосов
/ 08 ноября 2013

Обновление моего ответа с помощью Xcode 9 и Swift

Архив

xcodebuild -workspace <ProjectName>/<ProjectName>.xcworkspace -scheme <schemeName> clean archive -configuration release -sdk iphoneos -archivePath <ProjectName>.xcarchive

Экспорт IPA ( обратите внимание на список параметров экспорта )

xcodebuild -exportArchive -archivePath  <ProjectName>.xcarchive -exportOptionsPlist  <ProjectName>/exportOptions.plist -exportPath  <ProjectName>.ipa

Для тех, кто не знает о exportOptions.plist, https://blog.bitrise.io/new-export-options-plist-in-xcode-9


Те, кто использовал это для сборки проекта в инструментах CI / CD, таких как teamcity / jenkins, убедитесь, что вы используете правильный xcode, установленный в агенте сборки для архивации и экспорта.

Для этого вы можете использовать любой из двух вариантов.

  1. Используйте полный путь к xcodebuild,

/Applications/Xcode 9.3.1.app/Contents/Developer/usr/bin/xcodebuild

  1. Использовать xcode-select,

xcode-select -switch /Applications/Xcode 9.3.1.app


Ниже старый ответ

Вот скрипт командной строки для создания архива и пример IPA. У меня есть проект iPhone xcode, который находится в папке Desktop / MyiOSApp.

Выполняйте следующие команды одну за другой.

cd /Users/username/Desktop/MyiOSApp/

xcodebuild -scheme MyiOSApp archive \
    -archivePath /Users/username/Desktop/MyiOSApp.xcarchive

xcodebuild -exportArchive -exportFormat ipa \
    -archivePath "/Users/username/Desktop/MyiOSApp.xcarchive" \
    -exportPath "/Users/username/Desktop/MyiOSApp.ipa" \
    -exportProvisioningProfile "MyCompany Distribution Profile"

Это проверено с Xcode 5 и работает нормально для меня.

27 голосов
/ 01 мая 2010

Я использовал свой собственный скрипт для создания пакета ipa для специального распространения.

die() {
    echo "$*" >&2
    exit 1
}

appname='AppName'
config='Ad Hoc Distribution'
sdk='iphoneos3.1.3'
project_dir=$(pwd)

echo using configuration $config

echo updating version number
agvtool bump -all
fullversion="$(agvtool mvers -terse1)($(agvtool vers -terse))"
echo building version $fullversion

xcodebuild -activetarget -configuration "$config" -sdk $sdk build || die "build failed"

echo making ipa...
# packaging
cd build/"$config"-iphoneos || die "no such directory"
rm -rf Payload
rm -f "$appname".*.ipa
mkdir Payload
cp -Rp "$appname.app" Payload/
if [ -f "$project_dir"/iTunesArtwork ] ; then
    cp -f "$project_dir"/iTunesArtwork Payload/iTunesArtwork
fi

ipaname="$appname.$fullversion.$(date -u +%Y%m%d%H%M%S).ipa"
zip -r $ipaname Payload

echo finished making $ipaname

Скрипт также увеличивает номер версии. Вы можете удалить эту часть, если она не нужна. Надеюсь, это поможет.

24 голосов
/ 11 июня 2012

Мы разработали приложение для iPad с XCode 4.2.1 и хотели интегрировать сборку в нашу непрерывную интеграцию (Jenkins) для распространения OTA. Вот решение, которое я придумал:

# Unlock keychain
security unlock-keychain -p jenkins /Users/jenkins/Library/Keychains/login.keychain

# Build and sign app
xcodebuild -configuration Distribution clean build

# Set variables
APP_PATH="$PWD/build/Distribution-iphoneos/iPadApp.app"
VERSION=`defaults read $APP_PATH/Info CFBundleShortVersionString`
REVISION=`defaults read $APP_PATH/Info CFBundleVersion`
DATE=`date +"%Y%m%d-%H%M%S"`
ITUNES_LINK="<a href=\"itms-services:\/\/?action=download-manifest\&url=https:\/\/xxx.xxx.xxx\/iPadApp-$VERSION.$REVISION-$DATE.plist\">Download iPad2-App v$VERSION.$REVISION-$DATE<\/a>"

# Package and verify app
xcrun -sdk iphoneos PackageApplication -v build/Distribution-iphoneos/iPadApp.app -o $PWD/iPadApp-$VERSION.$REVISION-$DATE.ipa

# Create plist
cat iPadApp.plist.template | sed -e "s/\${VERSION}/$VERSION/" -e "s/\${DATE}/$DATE/" -e "s/\${REVISION}/$REVISION/" > iPadApp-$VERSION.$REVISION-$DATE.plist

# Update index.html
curl https://xxx.xxx.xxx/index.html -o index.html.$DATE
cat index.html.$DATE | sed -n '1h;1!H;${;g;s/\(<h3>Aktuelle Version<\/h3>\)\(.*\)\(<h3>&Auml;ltere Versionen<\/h3>.<ul>.<li>\)/\1\
${ITUNES_LINK}\
\3\2<\/li>\
<li>/g;p;}' | sed -e "s/\${ITUNES_LINK}/$ITUNES_LINK/" > index.html

Затем Jenkins загружает файлы ipa, plist и html на наш веб-сервер.

Это шаблон plist:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>items</key>
    <array>
        <dict>
            <key>assets</key>
            <array>
                <dict>
                    <key>kind</key>
                    <string>software-package</string>
                    <key>url</key>
                    <string>https://xxx.xxx.xxx/iPadApp-${VERSION}.${REVISION}-${DATE}.ipa</string>
                </dict>
                <dict>
                    <key>kind</key>
                    <string>full-size-image</string>
                    <key>needs-shine</key>
                    <true/>
                    <key>url</key>
                    <string>https://xxx.xxx.xxx/iPadApp.png</string>
                </dict>
                <dict>
                    <key>kind</key>
                    <string>display-image</string>
                    <key>needs-shine</key>
                    <true/>
                    <key>url</key>
                    <string>https://xxx.xxx.xxx/iPadApp_sm.png</string>
                </dict>
            </array>
            <key>metadata</key>
            <dict>
                <key>bundle-identifier</key>
                <string>xxx.xxx.xxx.iPadApp</string>
                <key>bundle-version</key>
                <string>${VERSION}</string>
                <key>kind</key>
                <string>software</string>
                <key>subtitle</key>
                <string>iPad2-App</string>
                <key>title</key>
                <string>iPadApp</string>
            </dict>
        </dict>
    </array>
</dict>
</plist>

Для настройки необходимо импортировать сертификат распределения и профиль обеспечения в цепочку ключей назначенного пользователя.

23 голосов
/ 31 октября 2013

Инструмент xcodebuild может создавать и экспортировать архивные продукты с флагом -exportArchive (начиная с Xcode 5). Шаг экспорта ранее был возможен только через интерфейс Xcode Organizer.

Первый архив вашего приложения:

xcodebuild -scheme <scheme name> archive

Учитывая $ARCHIVE_PATH (путь к файлу .xcarchive ), экспортируйте приложение из архива одним из следующих способов:

iOS .ipa Файл:

xcodebuild -exportArchive -exportFormat ipa -archivePath "$ARCHIVE_PATH" -exportPath "myApp.ipa" -exportProvisioningProfile "My App Provisioning profile"

Mac .app Файл:

xcodebuild -exportArchive -exportFormat app -archivePath "$ARCHIVE_PATH" -exportPath "myApp.app" -exportSigningIdentity "Developer ID Application: My Software Company"

В обеих командах аргументы -exportProvisioningProfile и -exportSigningIdentity являются необязательными. man xcodebuild для подробностей о семантике. В этих примерах в профиле обеспечения для сборки iOS указан профиль обеспечения распространения AdHoc, а в идентификаторе подписи для приложения Mac указан идентификатор разработчика для экспорта в качестве стороннего приложения (т.е. не распространяемого через Mac App Store). *

16 голосов
/ 28 июня 2011

Я нашел здесь некоторые другие ответы, которые трудно найти. Эта статья сделала, если для меня. Некоторые пути, возможно, должны быть абсолютными, как упоминалось в других ответах.

Команда:

xcrun -sdk iphoneos PackageApplication \
    "/path/to/build/MyApp.app" \
    -o "output/path/to/MyApp.ipa" \
    --sign "iPhone Distribution: My Company" \
    --embed "/path/to/something.mobileprovision"
15 голосов
/ 13 февраля 2011

Вы МОЖЕТЕ отказаться от сборки, как это делает XCode, так что вы можете протестировать и отправить тот же двоичный файл. Например, в моем сценарии (аналогичном описанному выше) я создаю свою версию выпуска, подписанную как сборку AdHoc, затем архивирую ее как IPA для тестирования, затем подаю в отставку с моим сертификатом распространения и создаю zip-файл, который я и отправляю Яблоко. Соответствующая строка:

codesign -f -vv -s "$DistributionIdentity" "$APPDIR"
14 голосов
/ 06 ноября 2015

Для Xcode 7 у вас есть гораздо более простое решение. Единственная дополнительная работа заключается в том, что вам нужно создать файл конфигурации plist для экспорта архива.

(По сравнению с Xcode 6 в результатах опций xcrun xcodebuild -help, -exportFormat и -exportProvisioningProfile больше не упоминается; первый удаляется, а второй заменяется -exportOptionsPlist.)

Шаг 1 , измените каталог на папку, включающую файл .xcodeproject или .xcworkspace.

cd MyProjectFolder

Шаг 2 , используйте Xcode или /usr/libexec/PlistBuddy exportOptions.plist для создания файла списка параметров экспорта. Кстати, xcrun xcodebuild -help скажет вам, какие ключи нужно вставить в файл plist.

Шаг 3 , создайте файл .xcarchive (фактически, папку) следующим образом (каталог / build будет автоматически создан XCode прямо сейчас),

xcrun xcodebuild -scheme MyApp -configuration Release archive -archivePath build/MyApp.xcarchive

Шаг 4 , экспортируйте как .ipa-файл следующим образом, который отличается от Xcode6

xcrun xcodebuild -exportArchive -exportPath build/ -archivePath build/MyApp.xcarchive/ -exportOptionsPlist exportOptions.plist

Теперь вы получаете файл ipa в каталоге build /. Просто отправьте его в Apple App Store.

Кстати, файл ipa, созданный Xcode 7, намного больше, чем Xcode 6.

14 голосов
/ 21 августа 2013

Ниже приведено краткое описание шагов, которые необходимо выполнить, и параметров, которые необходимо передать при создании ipa с использованием terrminal:

  1. Перейдите в папку, которая содержит файл MyApp.xcodeproject в терминале

  2. Используя приведенную ниже команду, вы получите все цели приложения

    /usr/bin/xcodebuild -list 
    
  3. После выполнения вышеупомянутой команды вы получите список целей, из которых вы должны выбрать конкретную цель, которую вы хотите сгенерировать .ipa

    /usr/bin/xcodebuild -target $TARGET -sdk iphoneos -configuration Release
    
  4. Приведенная выше команда создает проект и создает файл .app. Путь для поиска файла .app: ./build/Release-iphoneos/MyApp.app

  5. После успешного завершения сборки выполните следующую команду, чтобы сгенерировать .ipa приложения, используя Имя разработчика и Профиль обеспечения, используя следующий синтаксис:

    /usr/bin/xcrun -sdk iphoneos PackageApplication -v “${TARGET}.app” -o “${OUTDIR}/${TARGET}.ipa” –sign “${IDENTITY}” –embed “${PROVISONING_PROFILE}”
    

Объяснение каждого параметра в приведенном выше синтаксисе:

${TARGET}.app                == Target path (ex :/Users/XXXXXX/desktop/Application/build/Release-iphoneos/MyApp.app)
${OUTDIR}                    == Select the output directory(Where you want to save .ipa file)
${IDENTITY}                   == iPhone Developer: XXXXXXX (XXXXXXXXXX)(which can be obtained from Keychain access)
${PROVISONING_PROFILE}   == Path to the provisioning profile(/Users/XXXXXX/Library/MobileDevice/Provisioning Profiles/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX.mobileprovision”)
  1. ipa будет сгенерирован в выбранном выходном каталоге " $ {OUTDIR} "
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...