Как вы кодируете пакеты фреймворка для Mac App Store?

81

После недавней отправки я получил следующую ошибку:

Неверная подпись - вложенный пакет приложений (FooBar.app/Contents/Frameworks/GData.framework) не подписан, подпись недействительна или не подписана сертификатом отправки Apple. Дополнительные сведения см. В Руководстве по подписи кода и изолированной программной среде приложений.

Недопустимая подпись - вложенный пакет приложений (FooBar.app/Contents/Frameworks/Growl.framework) не подписан, подпись недействительна или не подписана сертификатом отправки Apple. Дополнительные сведения см. В Руководстве по подписи кода и изолированной программной среде приложений.

Недействительная подпись - вложенный пакет приложений libcurl (FooBar.app/Contents/Frameworks/libcurl.framework) не подписан, подпись недействительна или не подписана сертификатом отправки Apple. Дополнительные сведения см. В Руководстве по подписи кода и изолированной программной среде приложений.

Итак, я подписал все пакеты фреймворков на Technote 2206 :

codesign -f -v -s "3rd Party Mac Developer Application: Name" ./libcurl.framework/Versions/A/libcurl
codesign -f -v -s "3rd Party Mac Developer Application: Name" ./libcurl.framework/Versions/A/libssh2.1.dylib
codesign -f -v -s "3rd Party Mac Developer Application: Name" ./Growl.framework/Versions/A/Growl
codesign -f -v -s "3rd Party Mac Developer Application: Name" ./GData.framework/Versions/A/GData

Technote 2206 говорит:

Платформы подписи

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

# Это неправильный путь:

codeign -s моя-подписи-личность ../FooBarBaz.framework

# Это правильный путь:

codeign -s моя-подписи-личность ../FooBarBaz.framework/Versions/A

И когда я пытаюсь проверить результаты, мне кажется, что это хорошо:

% codesign -vvv FooBar.app/Contents/Frameworks/libcurl.framework
FooBar.app/Contents/Frameworks/libcurl.framework: valid on disk
FooBar.app/Contents/Frameworks/libcurl.framework: satisfies its Designated Requirement
% codesign -vvv FooBar.app/Contents/Frameworks/Growl.framework
FooBar.app/Contents/Frameworks/Growl.framework: valid on disk
FooBar.app/Contents/Frameworks/Growl.framework: satisfies its Designated Requirement

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

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

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

Csexton
источник
Я также обнаружил это ранее, когда отправил свое приложение. К счастью, Apple не отказалась от него, но отметила, что нам придется подписать фреймворки позже. Я думаю, что лучше опубликовать сообщение на странице проблем с кодом Growl google, и очень скоро люди столкнутся с той же проблемой.
koo
2
Также столкнулся с этой проблемой при отправке приложения с помощью платформы Growl. Я предполагаю, что вам придется изменить идентификатор пакета Growl.framework на тот, который у вас есть, а затем кодировать его.
Эндрю
Это странно: я опубликовал приложение, которое включает два фреймворка (CorePlot и MacRuby), оба без подписи. Я запускаю команду подписи кода в комплекте приложений только один раз, и приложение было принято без каких-либо комментариев к платформе. Теперь, если вы посмотрите на пакет приложений ( bit.ly/charterapp ), обе платформы кажутся подписанными. Вы пытались просто подписать все приложение?
p4010
@ p4010, я делал - раньше они были без подписи. Рычание, например, было просто прямой связкой, которую они раздают. У меня уже есть это приложение в магазине, поэтому я предполагаю, что это связано с новой песочницей. Когда вы отправили свое приложение?
csexton
@ Андрей, у вас сработало изменение идентификатора пакета?
csexton

Ответы:

46

На основе ответа baptr я разработал этот сценарий оболочки, который кодирует все мои фреймворки и другие двоичные ресурсы / вспомогательные исполняемые файлы (в настоящее время поддерживаемые типы: dylib, bundle и элементы входа в систему):

#!/bin/sh

# WARNING: You may have to run Clean in Xcode after changing CODE_SIGN_IDENTITY! 

# Verify that $CODE_SIGN_IDENTITY is set
if [ -z "${CODE_SIGN_IDENTITY}" ] ; then
    echo "CODE_SIGN_IDENTITY needs to be set for framework code-signing!"

    if [ "${CONFIGURATION}" = "Release" ] ; then
        exit 1
    else
        # Code-signing is optional for non-release builds.
        exit 0
    fi
fi

if [ -z "${CODE_SIGN_ENTITLEMENTS}" ] ; then
    echo "CODE_SIGN_ENTITLEMENTS needs to be set for framework code-signing!"

    if [ "${CONFIGURATION}" = "Release" ] ; then
        exit 1
    else
        # Code-signing is optional for non-release builds.
        exit 0
    fi
fi

ITEMS=""

FRAMEWORKS_DIR="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
if [ -d "$FRAMEWORKS_DIR" ] ; then
    FRAMEWORKS=$(find "${FRAMEWORKS_DIR}" -depth -type d -name "*.framework" -or -name "*.dylib" -or -name "*.bundle" | sed -e "s/\(.*framework\)/\1\/Versions\/A\//")
    RESULT=$?
    if [[ $RESULT != 0 ]] ; then
        exit 1
    fi

    ITEMS="${FRAMEWORKS}"
fi

LOGINITEMS_DIR="${TARGET_BUILD_DIR}/${CONTENTS_FOLDER_PATH}/Library/LoginItems/"
if [ -d "$LOGINITEMS_DIR" ] ; then
    LOGINITEMS=$(find "${LOGINITEMS_DIR}" -depth -type d -name "*.app")
    RESULT=$?
    if [[ $RESULT != 0 ]] ; then
        exit 1
    fi

    ITEMS="${ITEMS}"$'\n'"${LOGINITEMS}"
fi

# Prefer the expanded name, if available.
CODE_SIGN_IDENTITY_FOR_ITEMS="${EXPANDED_CODE_SIGN_IDENTITY_NAME}"
if [ "${CODE_SIGN_IDENTITY_FOR_ITEMS}" = "" ] ; then
    # Fall back to old behavior.
    CODE_SIGN_IDENTITY_FOR_ITEMS="${CODE_SIGN_IDENTITY}"
fi

echo "Identity:"
echo "${CODE_SIGN_IDENTITY_FOR_ITEMS}"

echo "Entitlements:"
echo "${CODE_SIGN_ENTITLEMENTS}"

echo "Found:"
echo "${ITEMS}"

# Change the Internal Field Separator (IFS) so that spaces in paths will not cause problems below.
SAVED_IFS=$IFS
IFS=$(echo -en "\n\b")

# Loop through all items.
for ITEM in $ITEMS;
do
    echo "Signing '${ITEM}'"
    codesign --force --verbose --sign "${CODE_SIGN_IDENTITY_FOR_ITEMS}" --entitlements "${CODE_SIGN_ENTITLEMENTS}" "${ITEM}"
    RESULT=$?
    if [[ $RESULT != 0 ]] ; then
        echo "Failed to sign '${ITEM}'."
        IFS=$SAVED_IFS
        exit 1
    fi
done

# Restore $IFS.
IFS=$SAVED_IFS
  1. Сохраните его в файл в своем проекте. Я храню свою копию в Scriptsподкаталоге в корне моего проекта.
    • Моя называется codesign-frameworks.sh.
  2. Добавьте этап сборки «Выполнить скрипт» сразу после фазы сборки «Копировать встроенные платформы».
    • Вы можете назвать это «Встроенные рамки Codesign».
  3. Вставьте ./codesign-frameworks.sh(или как вы назвали свой сценарий выше) в текстовое поле редактора сценариев. Используйте, ./Scripts/codesign-frameworks.shесли вы храните сценарий в подкаталоге.
  4. Создайте свое приложение. Все связанные фреймворки будут иметь кодовую подпись.

Если вы по-прежнему получаете сообщение об ошибке « Идентичность : неоднозначно (совпадает:…»), прокомментируйте, пожалуйста. Этого больше не должно происходить.

Обновлено 14.11.2012: добавлена ​​поддержка фреймворков со специальными символами в их имени (не включая одинарные кавычки) в «codeign-frameworks.sh».

Обновлено 30.01.2013: добавлена ​​поддержка специальных символов во всех путях (это должно включать одинарные кавычки) в «codeign-frameworks.sh».

Обновлено 29.10.2013: добавлена ​​экспериментальная поддержка dylib.

Обновлено 28.11.2013: добавление поддержки прав. Улучшение экспериментальной поддержки dylib.

Обновлено 13.06.2014: Устранение проблем с кодовой подписью в фреймворках, содержащих (вложенные) фреймворки. Это было сделано путем добавления -depthопции в find, которая заставляет findвыполнять обход в глубину. Это стало необходимым из-за проблемы, описанной здесь . Вкратце: содержащий пакет можно подписать, только если его вложенные пакеты уже подписаны.

Обновлено 28.06.2014: добавлена ​​поддержка экспериментального пакета.

Обновлено 22.08.2014: Улучшение кода и предотвращение сбоев при восстановлении IFS.

Обновлено 26.09.2014: добавлена ​​поддержка элементов входа в систему.

Обновлено 26.10.2014: Проверки каталогов. Это исправляет ошибки «строка 31/42: слишком много аргументов» и результирующая ошибка «объект кода вообще не подписан» для путей, содержащих специальные символы.

Обновлено 07.11.2014: Устранение неоднозначной ошибки идентификации (например, «Разработчик Mac: неоднозначно…») при использовании автоматического разрешения идентификации в Xcode. Вам больше не нужно явно устанавливать личность, и вы можете просто использовать «Mac Developer»!

Обновлено 07.08.2015: Улучшение семантики.

Улучшения приветствуются!

ЯнвX2
источник
Спасибо за это, просто примечание, это не сработает, если в имени вашей цели есть пробел. Я попытался исправить, но не смог заставить его работать, поэтому изменил цель.
Craig
Должно работать сейчас, когда в имени FRAMEWORK_DIR есть пробелы / специальные символы.
января,
Однако мне также нужно было отключить параметр отметки времени, добавив "--timestamp" в конец команды codeign.
Elmer Cat
Интересно. Вы, @Elmer Cat, случайно делаете это в невыпущенной версии OS X? На странице руководства описывается этот вариант «поведения по умолчанию, зависящего от системы».
JanX2
1
Элмер Кэт - я не знаю, какую версию Xcode вы используете, но я использую 5.0.1, и она определенно НЕ подписывает мои фреймворки автоматически. Я рвал волосы, пока не нашел этот сценарий.
Брайан
11

Ваш комментарий показывает, что вы подписали объекты в каталоге версий пакета. Technote показывает подписать сам каталог.

Следующее лучше соответствует Technote:

codesign -f -v -s "3rd Party Mac Developer Application: Name" ./libcurl.framework/Versions/A
codesign -f -v -s "3rd Party Mac Developer Application: Name" ./Growl.framework/Versions/A
codesign -f -v -s "3rd Party Mac Developer Application: Name" ./GData.framework/Versions/A
креститель
источник
4

Вот как я это исправил;

  • Войдите в настройки сборки вашей цели
  • Найдите строку «Другие флаги подписи кода».
  • Войти значение --deep в параметр выпуска
  • Закройте XCode
  • Войдите в папку производных данных на вашем Mac и удалите старые производные данные (путь по умолчанию: / Users / YOUR_USER_NAME / Library / Developer / Xcode / DerivedData)
  • Откройте Xcode и соберите

После архивации сборки и снова отправьте приложение ...

Emreoktem
источник
3
В мире грез "--deep" будет работать так, как ожидалось, но мы не живем в мире грез ...
Майк
0

Одна вещь, о которой я здесь не упоминаю, - это то, что вам нужно иметь свой Info.plist внутри / Resources внутри каталога версионной платформы. В противном случае вы получите ошибку «формат пакета нераспознан, недействителен или непригоден» при попытке подписать каталог с версией.

Я дал более развернутый ответ здесь: Как создать код Growl.framework для изолированного приложения Mac

Росс Бенцина
источник