Создание фреймворков iOS/OSX: необходимо ли их кодировать перед распространением среди других разработчиков?

Я учусь создавать платформы iOS и OSX. Давайте возьмем iOS, например, следующие шаги работают для меня до сих пор:

  1. фреймворк xcodebuild с использованием -sdk iphonesimulator и действия Build
  2. фреймворк xcodebuild с использованием -sdk iphoneos и действия Build
  3. Используйте липо инструмент, чтобы создать универсальный бинарный файл так, чтобы lipo -info производит ожидаемое:

Архитектуры в толстом файле: Foo.framework/Foo: i386 x86_64 armv7 arm64

Вопросы:

  1. Я прочитал, что мой фреймворк может быть повторно подписан разработчиком, который его использует: "Code Sign on Copy", но я не понимаю, каковы предварительные условия для этого, то есть я должен добавить шаг CoSignign для кодирования этого универсального двоичного файла с моей идентификационной подписью перед распространять это другим разработчикам?

  2. если предыдущий является положительным - достаточно ли использовать мою идентификацию "iPhone Distribution: ..." или "iPhone Developer: ..." (чтобы моя платформа, являющаяся частью какого-либо проекта iOS, прошла все виды проверок, особенно проверку App Store)?.

Основанием для моего ответа является "Ошибка CodeSign: подпись кода требуется для типа продукта" Framework "в SDK" iOS 8.3 "", который я видел на ряде сторонних фреймворков, и Carthage#235 или "объект кода не подписан". вообще "(один из примеров: проблема, о которой я сообщал в Realm # 1998.

Поэтому я хочу быть уверен, что пользователи моих фреймворков не столкнутся с какими-либо проблемами кодирования при их использовании.

PS Этот вопрос становится еще более интересным, когда он применяется не к одному разработчику, а к организации, которая является поставщиком фреймворка.

3 ответа

Решение

Я открыл награду: "В поисках ответа, полученного из достоверных и / или официальных источников". но с тех пор не получил такого.

Хотя ответ, предоставленный @jackslash, верен, он рассказывает только часть истории, поэтому я хочу написать свой собственный так, как мне хотелось бы, чтобы он был в тот момент, когда я задавал этот вопрос.

Актуальность этого ответа: июль 2015 года. Скорее всего, все изменится.

Прежде всего, давайте утверждать, что действия, необходимые для правильной подписи кода платформы, должны быть разделены на шаги, которые должен сделать Разработчик платформы, и шаги, которые должен предпринять Потребитель платформы.

TLDR;

Для фреймворка OSX: разработчик может свободно распространять фреймворк OSX без кодовой подписи, так как Consumer все равно перекодирует его.

Для фреймворка iOS: разработчик может свободно распространять фреймворк iOS без кодовой подписи, так как Consumer все равно перекодирует его, но Xcode заставляет разработчика кодировать их фреймворк при сборке для устройства iOS.

Из-за радара: "Фреймворки iOS, содержащие фрагменты симулятора, не могут быть отправлены в App Store" Потребитель фреймворка iOS вынужден запускать специальный скрипт, такой как "copy_frameworks" или "strip_frameworks", который использует lipo -remove убрать фрагменты симулятора из iOS-фреймворка и перекодировать подписанные фреймворки, потому что в этот момент его идентификационная информация о кодировке, какой бы она ни была (или не была), удаляется как побочный эффект lipo -remove манипуляция.

Более длинный ответ следует.


Этот ответ не является "полученным из достоверных и / или официальных источников", а скорее основан на ряде эмпирических наблюдений.

Эмпирическое наблюдение № 1: Потребителям все равно, потому что они будут повторно кодировать среду, которую они получают от разработчика

Бинарные дистрибутивы хорошо известных проектов с открытым исходным кодом на Github не имеют кодового обозначения. команда codesign -d -vvvv дает: "объект кода вообще не подписан" на всех двоичных платформах iOS и OSX, которые я использовал для исследования. Некоторые примеры: ReactiveCocoa и Mantle, Realm, PromiseKit.

Из этого наблюдения ясно, что авторы этих платформ предполагают, что они будут подписаны кодировкой Потребителем от его имени, т.е. Потребитель должен использовать либо флаг "Подписать код при копировании" в фазе сборки "Встроить рамки", предоставляемый XCode, либо использовать некоторую пользовательскую оболочку. скрипт, который делает то же самое вручную: кодирует подпись фреймворка от имени потребителя.

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

Эмпирическое наблюдение № 2, которое применимо только к iOS и является предметом заботы разработчика

В то время как Consumer не заботится о том, подписана ли платформа, которую он получает от разработчика, или нет, разработчику все равно нужно кодировать свою платформу iOS как часть процесса сборки, когда они собирают ее для устройства iOS, потому что в противном случае Xcode не будет собирать CodeSign error: code signing is required for product type 'Framework' in SDK 'iOS 8.1', Процитирую Джастина Спар-Саммерса:

Фреймворки OS X не нужно кодировать при сборке... К сожалению, Xcode требует, чтобы фреймворки iOS были кодированы во время сборки.

Это довольно хорошо отвечает на мой вопрос №2: идентичности "iPhone Developer" достаточно, чтобы уговорить Xcode, чтобы он создал iOS-каркас для устройства. Этот комментарий к Карфагену № 339 говорит о том же.

Эмпирическое наблюдение № 3: липоинструмент

Особое поведение инструмента lipo: при применении к бинарному фреймворку он всегда рекурсивно удаляет из него любые идентификаторы кодов: lipo -create/-remove codesigned framework ... -> not codesigned framework,

Это может быть ответом, почему все примеры в наблюдении № 1 вообще не имеют кодовой подписи: их идентификация кодовой маркировки стирается после применения липосакции, но, поскольку согласно наблюдению № 1, потребителю все равно, все в порядке.

Это наблюдение особенно актуально для следующего наблюдения № 4 о AppStore.

Эмпирическое наблюдение №4. Платформы iOS, содержащие фрагменты симулятора, не могут быть отправлены в App Store

Это широко обсуждается в: Царстве № 1163 и Карфагене № 188, и радар открыт: rdar: // 19209161.

Это целиком и полностью касается Consumer: для универсальной платформы iOS, которую Consumer включает в свое приложение, при создании приложения они должны запускать специальный сценарий (настраиваемая фаза Run Script), который удаляет фрагмент симулятора из двоичного файла этой инфраструктуры, чтобы приложение могло пройти проверку AppStore.

Хороший пример для бинарных фреймворков я нашел в Realm: strip-frameworks.sh.

Оно использует lipo удалить все фрагменты архитектур кроме ${VALID_ARCHS} и затем повторно кодирует его с помощью идентификатора потребителя - вот где начинается наблюдение № 3: framework необходимо повторно присвоить кодовую подпись из-за липо-манипуляций с ним.

В Carthage есть скрипт CopyFrameworks.swift, который делает то же самое со всеми фреймворками, включенными в Consumer: он удаляет фрагменты симулятора и перекодирует фреймворк от имени для Consumer.

Также есть хорошая статья: Удаление нежелательных архитектур из динамических библиотек в XCode.


Теперь обзор шагов, необходимых для создания iOS и OSX с точки зрения как разработчика, так и потребителя. Сначала проще:

OSX

Разработчик:

  1. Сборка OSX Framework
  2. Дает его потребителю

От разработчика не требуется никаких действий по кодированию.

Потребитель:

  1. Получает OSX Framework от разработчика
  2. Копирует фреймворк в каталог Frameworks / и автоматически подписывает его от имени потребителя как часть процесса "Code Sign on Copy".

IOS

Разработчик:

  1. Создает iOS-фреймворк для устройства. Xcode требует совместного проектирования, достаточно "iPhone Developer".
  2. Сборка iOS фреймворка для симулятора.
  3. Использует lipo, который производит универсальный iOS-фреймворк из двух предыдущих. В этот момент идентификация кодового обозначения 1 шага теряется: универсальный каркас двоичного файла "вообще не подписан", но это нормально, так как "Потребителю все равно".
  4. Дает его потребителю

Потребитель:

  1. Получает iOS Framework от разработчика
  2. Копирует фреймворк в каталог Frameworks / (этот шаг может быть избыточным в зависимости от сценария на шаге 3).
  3. Использует специальный сценарий как часть процесса сборки: этот сценарий лишает симулятор фрагментов iOS-платформы и затем повторно кодирует его от имени пользователя.

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

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

CodeSign error: code signing is required for product type 'Framework' in SDK 'iOS 8.1'

Неважно, с какой идентификационной информацией вы кодируете подпись фреймворка (iPhone Developer или iPhone Distribution), потому что, как вы отметили, фреймворк будет повторно помечен под кодовым знаком "код подписи при копировании". Это означает, что ваша платформа будет повторно кодирована соответствующим сертификатом из профиля разработчика потребителя платформы, когда ваша платформа будет скопирована в их приложение. Это означает, что с App Store проблем не будет, поскольку он будет видеть только окончательную подпись кода от потребителя платформы.

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

Ответ Станислава Панкевича, приведенный выше, очень правильный и правильный Но обратите внимание, что начиная с Xcode 9.4, среда IDE попросит вас отключить подписывание кода для iOS Cocoa Touch Frameworks. Apple сейчас говорит, что не рекомендуется кодировать подпись.framework.

Надеюсь, это поможет.

Другие вопросы по тегам