С Xcode 6 мы получаем возможность создавать собственный динамический Cocoa Frameworks
.
![enter image description here]()
Из-за:
Мы должны сделать жировую библиотеку для запуска проекта на устройствах и симуляторах. то есть поддерживать 32 и 64 бит в Framework.
Но я не нашел никаких руководств, как экспортировать универсальную жировую структуру для дальнейшей интеграции с другими проектами (и поделиться этой библиотекой с кем-то).
Вот мои шаги для воспроизведения:
![enter image description here]()
- Построить структуру и открыть ее в Finder:
![enter image description here]()
![enter image description here]()
- Добавьте эту структуру в другой проект
Фактический результат:
Но в итоге у меня все еще есть проблема с запуском проекта с этой структурой на устройствах и симуляторе сразу.
-
если я беру фреймворк из папки Debug-iphoneos
- он работает на устройствах
и получает ошибку на тренажерах: ld: symbol(s) not found for architecture i386
xcrun lipo -info CoreActionSheetPicker
Архитектуры в жирном файле: CoreActionSheetPicker: armv7 armv7s arm64
-
если я беру фреймворк из папки Debug-iphonesimulator
- он работает на симуляторах. и у меня есть ошибка на устройстве: ld: symbol(s) not found for architecture arm64
xcrun lipo -info CoreActionSheetPicker
Архитектуры в файле жира: CoreActionSheetPicker: i386 x86_64
Итак, как создать динамическую структуру, которая работает на устройствах и симуляторах?
Этот ответ связан с Xcode 6 iOS Создание Cocoa Touch Framework - проблемы с архитектурой, но он не дублируется.
Обновление:
Я нашел "грязный взлом" для этого случая. См. Мой ответ ниже.
Если кто-то знает более удобный способ - пожалуйста, дайте мне знать!
Ответ 1
Действительность этого ответа: июль 2015 года. Скорее всего, все изменится.
TL;DR;
В настоящее время Xcode не имеет инструментов для автоматического экспорта универсальной жировой структуры, поэтому разработчик должен прибегнуть к ручному использованию инструмента lipo
. Также в соответствии с этот радар перед представлением разработчику AppStore, являющемуся потребителем инфраструктуры, также должен использовать lipo
для удаления срезов симулятора из фреймворка.
Более длинный ответ следует
Я сделал аналогичные исследования в теме (ссылка внизу ответа).
Я не нашел официальной документации о распределении, поэтому мои исследования были основаны на исследовании проектов Apple Developer, проектов Carthage и Realm и моих собственных экспериментов с инструментами xcodebuild
, lipo
, codesign
.
Здесь длинная цитата (с небольшим разметкой от меня) от форума разработчиков Apple Экспорт приложения со встроенной инфраструктурой:
Каков правильный способ экспорта фреймворка из проекта framework?
В настоящее время единственный способ - это именно то, что вы сделали:
- Создайте цель как для симулятора, так и для устройства iOS.
-
Перейдите в папку Xcode DerivedData для этого проекта и переместите два двоичных файла вместе в одну единую структуру. Однако, когда вы создаете целевую среду фреймворка в Xcode, не забудьте настроить целевой параметр "Build Active Architecture Only" на "NO". Это позволит Xcode строить цель для нескольких типов бинарти (arm64, armv7 и т.д.). Вот почему он работает с Xcode, но не как автономный двоичный файл.
-
Также вы захотите убедиться, что схема настроена на сборку Release и построит целевую среду framework для выпуска. Если вы все еще получаете ошибку, не загруженную библиотекой, проверьте фрагменты кода в фреймворке.
- Используйте
lipo -info MyFramworkBinary
и просмотрите результат.
lipo -info MyFrameworkBinary
Результат i386 x86_64 armv7 arm64
- Современные универсальные рамки будут включать в себя 4 среза, но могут включать в себя больше:
i386 x86_64 armv7 arm64
Если вы не видите по крайней мере этого 4, это связано с настройкой Build Active Architecture.
Это описывает процесс почти так же, как @skywinder сделал это в своем ответе.
Вот как Карфаген использует липо и Realm использует lipo.
ВАЖНАЯ ДЕТАЛИ
Существует радар: Xcode 6.1.1 и 6.2: рамки iOS, содержащие ломтики симулятора, не могут быть отправлены в App Store и длинными обсуждение вокруг него на Realm # 1163 и Карфаген # 188, который закончилась специальным обходом:
перед отправкой в AppStore бинарные файлы инфраструктуры iOS должны быть удалены из ломтиков симулятора
У Карфагена есть специальный код: CopyFrameworks и соответствующий фрагмент документации:
Этот script работает вокруг Ошибка представления App Store, вызванного универсальными двоичными файлами.
В Realm есть специальный script: strip-frameworks.sh и соответствующий фрагмент документации:
Этот шаг необходим для работы с ошибкой представления Store Store при архивировании универсальных двоичных файлов.
Также есть хорошая статья: Удаление нежелательных архитектур из динамических библиотек в Xcode.
Я сам использовал Realm strip-frameworks.sh
, который работал у меня совершенно без каких-либо изменений, хотя, конечно, любой может свободно писать с нуля.
Ссылка на мою тему, которую я рекомендую читать, потому что она содержит другой аспект этого вопроса: подписание кода - Создание iOS/OSX Framework: необходимо ли их кодовое кодирование перед распространением на другие разработчики?
Ответ 2
Это не столь ясное решение, но есть только способ, который я нахожу:
![enter image description here]()
![enter image description here]()
- Запустите this script из
Products
. В этой папке создается fat Framework. (или сделайте это вручную, как описано ниже в разделе 3. 4.)
Или:
-
Объедините эти 2 Framework с помощью lipo с помощью этого script (замените YourFrameworkName
на ваше имя Framework)
lipo -create -output "YourFrameworkName" "Debug-iphonesimulator/YourFrameworkName.framework/YourFrameworkName" "Debug-iphoneos/YourFrameworkName.framework/YourFrameworkName"
-
Замените новую двоичную одну из существующих фреймворков:
cp -R Debug-iphoneos/YourFrameworkName.framework ./YourFrameworkName.framework
mv YourFrameworkName ./YourFrameworkName.framework/YourFrameworkName
- Прибыль:
./YourFrameworkName.framework
- - готовый к использованию жирный бинарный! Вы можете импортировать его в свой проект!
Для проекта это не в Workspaces:
Вы также можете попытаться использовать этот смысл, как описано здесь. Но кажется, что он не работает для проектов в рабочих пространствах.
Ответ 3
Ответ на @Stainlav был очень полезным, но вместо этого я должен был скомпилировать две версии фреймворка (один для устройства и один для симулятора), а затем добавил следующий Run Script Phase
, чтобы автоматически копировать предварительно скомпилированную фреймворк, необходимый для работы архитектура
echo "Copying frameworks for architecture: $CURRENT_ARCH"
if [ "${CURRENT_ARCH}" = "x86_64" ] || [ "${CURRENT_ARCH}" = "i386" ]; then
cp -af "${SRCROOT}/Frameworks/Simulator/." "${SRCROOT}/Frameworks/Active"
else
cp -af "${SRCROOT}/Frameworks/Device/." "${SRCROOT}/Frameworks/Active"
fi
Таким образом, я не использую lipo
для создания живого фрейма, а не для Realm strip-frameworks.sh
для удаления ненужных фрагментов при отправке в App Store.
Ответ 4
в основном для этого я нашел очень хорошее решение. вам просто нужно выполнить эти простые шаги.
- Создайте структуру cocoa touch.
- Установить бит-код с номером.
- Выберите цель и выберите схемы редактирования. Выберите "Выполнить" и выберите "Выйти из вкладки" Информация ".
- Никакой другой настройки не требуется.
- Теперь создадим фреймворк для любого симулятора, поскольку симулятор работает на архитектуре x86.
- Выберите группу продуктов в Навигаторе проектов и найдите файл .framework.
- Щелкните правой кнопкой мыши по нему и нажмите "Показать в поиске". Скопируйте и вставьте его в любую папку, я лично предпочитаю имя "симулятор".
- Теперь создадим структуру для универсального устройства iOS и следуйте инструкциям с 6 по 9. Просто переименуйте папку в "устройство" вместо "симулятора".
- Скопируйте файл .framework и вставьте его в любой другой каталог. Я предпочитаю немедленный супер-каталог обоих.
Таким образом, структура каталогов теперь становится:
- Desktop
- Устройство
- Тренажер
- MyFramework.framework
Теперь откройте терминал и cd на рабочем столе. Теперь начните вводить следующую команду:
lipo -create 'device/MyFramework.framework/MyFramework' 'simulator/MyFramework.framework/MyFramework' -output 'MyFramework.framework/MyFramework
и что он. Здесь мы объединяем симулятор и версию устройства двоичного файла MyFramework, присутствующего в MyFramework.framework. Мы получаем универсальную структуру, которая строит для всех архитектур, включая симулятор и устройство.
Ответ 5
Мой ответ охватывает следующие пункты:
-
Создайте фреймворк, который работает как для симулятора, так и для устройства
-
Как экспортировать "жир" Cocoa Touch Framework (для Simulator и устройства оба)?
-
Undefined символы для архитектуры x86_64
-
ld: символы (символы), не найденные для архитектуры x86_64
Шаги 1: сначала создайте свои фреймворки с помощью цели Simulator
Шаги 2: После успеха процесса сборки симулятора теперь создайте для своей рамки с выбором целевого устройства или универсальным выбором устройства iOS
Шаг 3: Теперь выберите целевую среду фрейма и для этого. В разделе "Фазы сборки" выберите "Добавить запуск Script" и скопируйте приведенный ниже код script)
Шаг4: Теперь, наконец, снова создайте, и ваша инфраструктура готова к совместимости с имитатором и устройством. Ура!!!!
[Примечание. Перед окончательным шагом4 мы должны иметь совместимую фреймворк (совместим с имитатором и архитектурой устройства, если не выполните правильные шаги 1 и 2)
См. контрольное изображение:
![введите описание изображения здесь]()
![введите описание изображения здесь]()
Поместите ниже код в область оболочки:
#!/bin/sh
UNIVERSAL_OUTPUTFOLDER=${BUILD_DIR}/${CONFIGURATION}-universal
# make sure the output directory exists
mkdir -p "${UNIVERSAL_OUTPUTFOLDER}"
# Step 1. Build Device and Simulator versions
xcodebuild -target "${PROJECT_NAME}" ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphoneos BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build
xcodebuild -target "${PROJECT_NAME}" -configuration ${CONFIGURATION} -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build
# Step 2. Copy the framework structure (from iphoneos build) to the universal folder
cp -R "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework" "${UNIVERSAL_OUTPUTFOLDER}/"
# Step 3. Copy Swift modules from iphonesimulator build (if it exists) to the copied framework directory
SIMULATOR_SWIFT_MODULES_DIR="${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework/Modules/${PROJECT_NAME}.swiftmodule/."
if [ -d "${SIMULATOR_SWIFT_MODULES_DIR}" ]; then
cp -R "${SIMULATOR_SWIFT_MODULES_DIR}" "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework/Modules/${PROJECT_NAME}.swiftmodule"
fi
# Step 4. Create universal binary file using lipo and place the combined executable in the copied framework directory
lipo -create -output "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework/${PROJECT_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework/${PROJECT_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework/${PROJECT_NAME}"
# Step 5. Convenience step to copy the framework to the project directory
cp -R "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework" "${PROJECT_DIR}"
# Step 6. Convenience step to open the project directory in Finder
open "${BUILD_DIR}/${CONFIGURATION}-universal"