Проблема со сборкой и подписью приложения iOS с настраиваемым идентификатором пакета для поддержки нескольких конфигураций сборки

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

Я очень далеко продвинулся в том, чтобы заставить эту работу работать, но у меня возникают проблемы с кодовой подписью приложения с автоматически сгенерированным идентификатором пакета (один работает с переменной).

ЧТО Я СДЕЛАЛ ТАК ДАЛЕКО

Я использую xCode 4.6.3, используя специальный профиль подготовки.

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

  • UXXXXXX.au.com.blah.MOCK
  • UXXXXXX.au.com.blah.DEV
  • UXXXXXX.au.com.blah.TEST
  • UXXXXXX.au.com.blah.PROD

Поэтому мой идентификатор пакета в моем информационном списке был настроен как "UXXXXXX.au.com.blah. $ {BUNDLE_SUFFIX}"

Теперь, чтобы позволить мне создавать приложение по-разному для каждой сборки, я сделал следующее:

  • У меня есть 4 разных идентификатора пакета с 4 разными профилями подготовки, назначенными этим идентификаторам пакета
  • Для начала я добавил новую конфигурацию под названием «MOCK» (остальные я добавлю позже).
  • Затем в настройках сборки проекта я добавил в свой проект пользовательскую переменную BUNDLE_SUFFIX и установил для нее значение MOCK для конфигурации MOCK (остальные я добавлю позже). Это используется для установки идентификатора пакета для сборки, которая использует конфигурацию MOCK.
  • Затем в настройках сборки проекта выберите мой профиль обеспечения MOCK для конфигурации MOCK в настройках сборки.
  • Я замечаю, что если я перехожу к сводному представлению в моем целевом приложении, он отображает идентификатор пакета как UXXXXXX.au.com.blah.MOCK с частью 'MOCK' серым шрифтом, поэтому он взял переменную суффикса пакета
  • Затем я создал новую схему под названием MOCK, чтобы использовать конфигурацию MOCK для «Профиля» и «Архива». Для остальных я оставил значения по умолчанию (использует DEBUG).

Итак, теперь я могу запустить xcodebuild и использовать схему MOCK для создания конкретной сборки MOCK, которая будет использовать конфигурацию MOCK для установки идентификатора пакета в .MOCK и установки моего профиля Provisoning на использование профиля _MOCK.

Затем я запускаю сборку jenkins, которая выполняет xcodebuild и xcrun (которая вызывает кодовый знак).

Это моя команда xcodebuild:

/usr/bin/xcodebuild -scheme MOCK -sdk iphoneos -project MyApp.xcodeproj -configuration MOCK clean build "CONFIGURATION_BUILD_DIR=/Users/CI/Documents/workspace/build3" ONLY_ACTIVE_ARCH=NO DEPLOY_ENVIRONMENT=MOCK "CODE_SIGN_IDENTITY=iPhone Distribution: My Company" "PROVISIONING_PROFILE=XXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"

Это моя команда xcrun:

/usr/bin/xcrun -sdk iphoneos PackageApplication -v "/Users/Shared/Jenkins/Home/jobs/MyApp.app" -o "/Users/Shared/Jenkins/Home/jobs/MyApp/workspace/build/MyApp-0.9.5.0.ipa" --embed "/Users/Shared/Jenkins/Home/Library/MobileDevice/Provisioning Profiles/20130816_Distribution_MOCK.mobileprovision" --sign "iPhone Distribution: My Company"

ПРИМЕЧАНИЕ. Я специально подписываю приложение с помощью профиля подготовки MOCK, поскольку я понял, что не могу подписать приложение с профилем. *, Поскольку приложение использует push-уведомления, и если я создам приложение с. *, А затем повторно подписываю приложение с правильным профилем, мой профиль embedded.mobileprovision обновляется, но фактический исполняемый файл в файле .app никогда не обновляется. И это приводит к тому, что push-уведомления никогда не попадают на устройство. Итак, что мне нужно для работы, так это возможность создавать и подписывать приложение из командной строки с приложением, имеющим идентификатор пакета, который заполняется динамически с помощью переменной. И я не могу заставить это работать.

РЕЗУЛЬТАТЫ

Xcodebuild успешно работает и отлично работает. Кажется, что приложение создано и правильно подписано как .MOCK и использует профиль обеспечения _MOCK!

НО! Возникла проблема с созданием файла IPA, у меня проблема с кодом.

Обратите внимание, что я создал приложение без каких-либо прав для подписи кода. codeign дает мне эту ошибку: предупреждение: приложение не прошло проверку кода. Подпись недействительна, содержит запрещенные права или не подписана сертификатом распространения iPhone. (-19011) Исполняемый файл = / Users / CI / Documents / workspace / build3 / MyApp.app / MyApp codeign_wrapper-4.1: использование Apple CA для оценки профиля Пара ключей / значений незаконных прав: идентификатор приложения, UXXXXXX.au. com.blah. AssertMacros: filter_entitlements (members_whitelist, entity_requested, allowable_entitlements), файл: codesign_wrapper.c, строка: 932 - (null

Обратите внимание, что пакет bundle_suffix не получен. Кроме того, когда я просматриваю файл MyApp.xcent, содержащий ссылки на кодовые обозначения, я замечаю, что в нем есть UXXXXXX.au.com.blah.. Он не получил значение bundle_suffix!

Итак, я попытался создать файл grantlements.plist для моей конфигурации сборки MOCK и добавить ссылку на файл в разделе «Права подписи кода» для конфигурации MOCK в настройках сборки. Но теперь у меня другая ошибка, и это довольно тревожно:

/usr/bin/codesign --force --sign 5XXXXXXXXXXXXXXXXXXX2c --resource-rules=/Users/CI/Documents/workspace/build3/MyApp.app/ResourceRules.plist --entitlements /Users/CI/Library/Developer/Xcode/DerivedData/MyApp-fasiktlyysoxjpgalujkfjpyiyeo/Build/Intermediates/MyApp.build/MOCK-iphoneos/MyApp.build/MyApp.xcent /Users/CI/Documents/workspace/build3/MyApp.app

Проверить /Users/CI/Documents/workspace/build3/MyApp.app cd / Users / Shared / Jenkins / Home / jobs / MyApp-MOCK-HourlyBuilds / workspace setenv PATH "/Applications/Xcode.app/Contents/Developer/Platforms/ iPhoneOS.platform / Developer / usr / bin: /Applications/Xcode.app/Contents/Developer/usr/bin: / usr / bin: / bin: / usr / sbin: / sbin: / usr / local / bin: / usr / local / git / bin "setenv PRODUCT_TYPE com.apple.product-type.application /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/Validation / Users / CI / Documents / workspace /build3/MyApp.app предупреждение: этот пакет недействителен. Право идентификатора приложения отформатировано неправильно; он должен содержать ваше 10-символьное начальное число идентификатора приложения, за которым следует точка, за которой следует идентификатор вашего пакета: UXXXXXXXX.au.com.amp.blah.MOCK (-19054) Невозможно проверить ваше приложение. - (null)

На этот раз он действительно получил правильный идентификатор пакета !! Он говорит MOCK it it. Но он жалуется на то, что этот комплект недействителен ... но мне кажется, что он вполне действителен !! Почему не работает?

Это мой файл grantlements.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>application-identifier</key>
    <string>UXXXXXXXXXXX.au.com.amp.blah.MOCK</string>
    <key>aps-environment</key>
    <string>production</string>
    <key>get-task-allow</key>
    <false/>
    <key>keychain-access-groups</key>
    <array>
            <string>UXXXXXXXXXXX.au.com.amp.blah.MOCK</string>
    </array>
</dict>
</plist>

Любая помощь будет принята с благодарностью, большое спасибо!

P.S. Я знаю, что способ обойти эту проблему - создать разные цели для каждой из моих сборок. Но я действительно не хочу этого, так как поддерживать несколько целей - это боль. Я действительно хотел попытаться уйти от этого, не имея нескольких целей, если смогу.

P.S.S. Я знаю, что другой способ обойти эту проблему - сначала подписать приложение с помощью профиля подготовки. *, А затем отказаться от приложения с соответствующим профилем, однако это не работает для меня. Поскольку исполняемый файл в .app по-прежнему сохраняет ссылки на профиль обеспечения. *. Таким образом, это устройство никогда не сможет принять push-уведомления. Я получаю сообщение об ошибке «Для приложения не найдена допустимая строка полномочий 'aps-environment'».


person jreeve    schedule 08.11.2013    source источник


Ответы (1)


Я запускаю аналогичную настройку для своих сборок iOS через Jenkins с целью разрешить параллельную установку приложения (производство, постановка, qa, dev) и столкнулся с той же проблемой, что и вы.

В конце концов, я наткнулся на этот ответ и изменил его, включив в него файл .xcent, который является частью xcodebuild (проверьте построить вывод для пути) для флага --entitlements. Это означает, что вам не нужно вручную создавать файл прав, но вы можете использовать именно тот, который xcodebuild создает для вас.

Я тоже использовал xcrun PackageApplication, но он НЕ поддерживает права, поэтому повторная подпись с использованием этого инструмента приведет к потере прав.

Итак, после запуска xcodebuild я использую plistbuddy для изменения моего файла info.plist, чтобы обновить пакет настроек и т. Д. (Это может не потребоваться для вас), и я распаковываю ipa, копирую профиль и info.plist в распакованную полезную нагрузку, переподписать и перепаковать:

pushd ${SCRIPT_DIR}
unzip "${PROJECT_NAME}.${CURRENT_ENV_NAME}.ipa"
rm -r "Payload/${PROJECT_NAME}.app/_CodeSignature" "Payload/${PROJECT_NAME}.app/CodeResources" 2> /dev/null | true
cp "${PROFILE}" "Payload/${PROJECT_NAME}.app/embedded.mobileprovision"
cp "${BUILD_DIR}/${BUILD_TARGET}-iphoneos/${PROJECT_NAME}.app/Info.plist" "Payload/Yappem.app/Info.plist"
/usr/bin/codesign -f -s "${CODE_SIGN_IDENTITY}" --resource-rules "Payload/${PROJECT_NAME}.app/ResourceRules.plist" --entitlements "${XCENT_FILE}" "Payload/${PROJECT_NAME}.app"
if [ $? != 0 ]; then
  echo Error Signing Project
  exit 1
fi
rm "${PROJECT_NAME}.${CURRENT_ENV_NAME}.ipa"
zip -qr "${PROJECT_NAME}.${CURRENT_ENV_NAME}.ipa" Payload
popd
person cbedrosian    schedule 27.12.2013