Як експортувати “жирну” рамку какао-сенсорного режиму (для симулятора та пристрою)?


107

За допомогою Xcode 6 ми отримуємо можливість створювати власні Dynamic Cocoa Frameworks.

введіть тут опис зображення

Тому що:

  • Симулятор досі користується 32-bitбібліотекою

  • Починаючи з 1 червня 2015 року оновлення додатків, що надсилаються в App Store, повинні включати 64-бітну підтримку та створювати її за допомогою iK 8 SDK ( developer.apple.com )

Ми повинні створити жирову бібліотеку для запуску проекту на пристроях та тренажерах. тобто підтримують як 32, так і 64 біт у Frameworks.

Але я не знайшов ніяких посібників, як експортувати універсальний жировий фреймворк для подальшої інтеграції з іншими проектами (і ділитися цією бібліотекою з кимось).

Ось мої кроки до відтворення:

  1. Встановити ONLY_ACTIVE_ARCH=NOвBuild Settings

    введіть тут опис зображення

  2. Додати підтримку armv7 armv7s arm64 i386 x86_64в Architectures(обов'язково)

введіть тут опис зображення

  1. Створіть Framework і відкрийте його в Finder:

введіть тут опис зображення введіть тут опис зображення

  1. Додайте цю рамку до іншого проекту

Фактичний результат:

Але врешті-решт у мене все ще виникає проблема із запуском проекту з цією рамкою на пристроях та симуляторі.

  • якщо я беру фреймворк з 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 - проблеми з архітектурою, але це не дублікат.


Оновлення:

Я знайшов "брудний злом" для цієї справи. Дивіться мою відповідь нижче . Якщо хтось знає більш зручний спосіб - будь ласка, дайте мені знати!



@ AndriusSteponavičius ці питання задавали 2 місяці раніше.
skywinder

Так, але є набагато докладніші відповіді, про які я думаю, що користувачі повинні знати про них
Андрій Степонавічус

Встановити ONLY_ACTIVE_ARCH = НІ в налаштуваннях збірки - важливий крок.
Джедіджа

ваша рамка потребує обох скибочок i386 x86_64 у жировій бінарці, якщо ви хочете запустити її на тренажері ВІДКЛЮЧЕНО, якщо ваш комп'ютер має 64-бітну архітектуру !!! Навчився тому важкий шлях.
J.beenie

Відповіді:


82

Актуальність цієї відповіді: липень 2015 року. Найімовірніше, що все зміниться.

TLDR;

В даний час Xcode не має інструментів для автоматичного експорту універсальної жирової бази, тому розробник повинен вдатися до ручного використання lipoінструменту. Також згідно з цим радіолокатором перед подачею розробнику AppStore, який є споживачем фреймворку, також потрібно використовувати lipoдля відсікання фрагментів симулятора з рамки.

Випливає довша відповідь


Я робив подібні дослідження в темі (посилання внизу відповіді).

Я не знайшов яких - небудь офіційних документів про розподіл так що моє дослідження було засноване на дослідженні Форумів компанії Apple для розробників, Карфагені і Realm проектів і моїх власних експериментів з xcodebuild, lipo, codesignінструменти.

Ось довга цитата (з невеликою розміткою від мене) від Apple Developers Forums Експорт програми з вбудованою рамкою :

Який правильний спосіб експорту рамки з рамкового проекту?

Наразі єдиний спосіб - це саме те, що ви зробили:

  • Побудувати ціль як для симулятора, так і для пристрою iOS
  • Перейдіть у папку DerivedData Xcode для цього проекту та об'єднайте два бінарні файли разом в один єдиний фреймворк. Однак, будуючи ціль рамки в Xcode, переконайтесь, що налаштуйте цільовий параметр "Зробити лише активну архітектуру" на "НІ". Це дозволить Xcode створити ціль для декількох типів бінарні (arm64, armv7 тощо). Тому це працює з Xcode, але не як окремий двійковий файл.

  • Також ви хочете переконатися, що схема встановлена ​​на версію Release і побудуйте рамкову ціль проти випуску. Якщо ви все ще отримуєте помилку з завантаженою бібліотекою, перевірте фрагменти коду в рамках.

  • Використовуйте lipo -info MyFramworkBinaryта вивчайте результат.

lipo -info MyFrameworkBinary

Результат є i386 x86_64 armv7 arm64

  • Сучасні універсальні рамки включатимуть 4 фрагменти, але вони можуть включати більше: i386 x86_64 armv7 arm64 Якщо ви не бачите принаймні цього 4, це може бути через налаштування Build Active Architecture.

Це описує процес так само, як і @skywinder зробив це у своїй відповіді.

Ось як Карфаген використовує lipo, а Realm використовує lipo .


ВАЖЛИВА ДЕТАЛІ

Існує радар: Xcode 6.1.1 та 6.2: рамки iOS, що містять фрагменти симулятора, не можуть бути подані до App Store, і довгі дискусії навколо нього на Realm № 1163 та Carthage № 188, які закінчилися спеціальним способом вирішення:

перед подачею на бінарні файли фреймворку AppStore iOS необхідно позбавити їх від зрізів симулятора

Карфаген має спеціальний код: CopyFrameworks та відповідний документ:

Цей сценарій працює над помилкою подання в App Store, ініційованою універсальними бінарними файлами.

У Realm є спеціальний сценарій: strip-frameworks.sh та відповідна частина документації:

Цей крок необхідний для усунення помилки подання App Store під час архівування універсальних бінарних файлів.

Також є хороша стаття: Зняття небажаних архітектур з динамічних бібліотек у Xcode .

Я сам використав Realm, strip-frameworks.shякий працював на мене ідеально без будь-яких модифікацій, хоча, звичайно, кожен вільний написати його з нуля.


Посилання на мою тему, яку я рекомендую прочитати, оскільки містить ще один аспект цього питання: підписання коду - Створення фреймворків iOS / OSX: чи потрібно кодувати їх перед розповсюдженням іншим розробникам?


1
Я використовував lipo, але коли Framework будується в симуляторі, він показує невирішений ідентифікатор з назвою класу, але в пристрої він працює. Якщо ви використовуєте симулятор бінарної версії, то це працює ..яка ідея?
Сусим Саманта

2
Я не знайшов жодних доказів, що це змінилося на Xcode 8.2 в грудні 2016 року: /
Джеффрі Вісман

1
@Geoffrey, це змінилося в Xcode 9.2 чи щось інше? Це вперше я створюю бінарні рамки для розповсюдження, і я вже боюся ...
ScottyB

Не зробив цього трохи, на жаль - не можу сказати. Удачі.
Джеффрі Вісман

57

Це не настільки чітке рішення, але я можу знайти:

  1. Встановити ONLY_ACTIVE_ARCH=NOвBuild Settings

    • Побудувати бібліотеку для тренажера
    • Збірка бібліотеки для пристрою
  2. Відкрити в Productsпапці консолі для вашої основи (ви можете відкрити її, відкривши папку Framework і cd ..звідти)

введіть тут опис зображення введіть тут опис зображення

  1. Запустіть цей скрипт із Productsпапки. Це створює жировий фреймворк у цій папці. (або зробіть це вручну, як пояснено нижче в 3. 4. )

Або:

  1. Поєднайте ці 2 рамки за допомогою lipo за цим сценарієм (замініть YourFrameworkNameна своє ім'я Framework)

    lipo -create -output "YourFrameworkName" "Debug-iphonesimulator/YourFrameworkName.framework/YourFrameworkName" "Debug-iphoneos/YourFrameworkName.framework/YourFrameworkName"
  2. Замініть новим бінарним одним із існуючих рамок:

    cp -R Debug-iphoneos/YourFrameworkName.framework ./YourFrameworkName.framework
    mv YourFrameworkName ./YourFrameworkName.framework/YourFrameworkName
    

  1. Прибуток: ./YourFrameworkName.framework- готовий до вживання жирний бінарний! Ви можете імпортувати його у свій проект!

Для проекту, що не в робочих просторах:

Ви також можете спробувати використати цю суть, як описано тут . Але здається, що це не працює для проектів у робочих просторах.


Я думав, що Apple більше не приймає жирових поживок. kodmunki.wordpress.com/2015/03/04/…
Монсьєр

1
@skywinder Ви знайшли якийсь інший простий спосіб експорту Cocoa Touch Framework, щоб готовий використовувати бінарний жир? Я використовую той же підхід, що і вище, але мені це не подобається. У Xcode повинні бути деякі, що автоматизують процес.
грунт гр.

1
@devgr ще не був. Тому я не прийняв власну відповідь. Ще шукаю кращого рішення.
skywinder

1
Не вдається запустити в тренажері, але працює в пристрої з 3 та 4 кроками
jose920405

1
@може хтось пояснить, чому використовується лише Debug-папка lipo -create? Чи можна цей фреймворк використовувати для Releaseконфігурації і чому? Дякую.
Євген Дубінін

10

Відповідь @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для створення жирної основи, ані Царства strip-frameworks.shдля видалення непотрібних скибочок під час подання в App Store.


З ким ви пов'язуєте?
Яка Янчар

@ JakaJančar Я пов'язую їх із ${SRCROOT}/Frameworks/Activeпапками. Їх замінюють на потрібні попередньо складені рамки для активної архітектури під час компіляції.
ом

2
Любіть це! Це набагато простіше, ніж lipoпідхід комбінувати, а потім розривати .
clozach

2

в основному для цього я знайшов дуже хороше рішення. вам просто потрібно дотримуватися цих простих кроків.

  1. Створіть рамку дотику какао.
  2. Встановити біт-код увімкнено Ні
  3. Виберіть ціль і виберіть схеми редагування. Виберіть Запуск та виберіть Відпустити на вкладці Інформація.
  4. Інші настройки не потрібні.
  5. Тепер побудуйте основу для будь-якого симулятора, оскільки тренажер працює на архітектурі x86.
  6. Клацніть на Групу продуктів у Навігаторі проекту та знайдіть файл .framework.
  7. Клацніть правою кнопкою миші та натисніть Показати у пошуку. Скопіюйте та вставте її в будь-яку папку, я особисто віддаю перевагу назві «симулятор».
  8. Тепер побудуйте основу для загального пристрою iOS та виконайте дії з 6 по 9. Просто перейменуйте папку на «пристрій», а не на «симулятор».
  9. Скопіюйте .framework файл пристрою та вставте в будь-який інший каталог. Я віддаю перевагу безпосередньому супер каталогу обох. Тож структура каталогу зараз стає:
    • Настільний
    • пристрій
      • MyFramework.framework
    • тренажер
      • MyFramework.framework
    • MyFramework.framework Тепер відкрийте термінал і перейдіть на робочий стіл. Тепер почніть вводити таку команду:

lipo -create 'пристрій / MyFramework.framework / MyFramework' 'симулятор / MyFramework.framework / MyFramework' -output 'MyFramework.framework / MyFramework'

і це все. Тут ми об'єднуємо імітатор та версію пристрою бінарного файлу MyFramework, присутнього всередині MyFramework.framework. Ми отримуємо універсальну основу, яка будується для всіх архітектур, включаючи симулятор та пристрій.


Я хочу створити файл FAT з включеним біт-кодом. Будь ласка, направляйте мене.
користувач3898700

2

Я просто хочу оновити цю чудову відповідь від @odm. Оскільки Xcode 10, CURRENT_ARCHзмінна більше не відображає архітектуру збірки. Тому я змінив сценарій, щоб перевірити платформу:

echo "Copying frameworks for platform: $PLATFORM_NAME"
rm -R "${SRCROOT}/Frameworks/Active"
if [ "${PLATFORM_NAME}" = "iphonesimulator" ]; then
    cp -af "${SRCROOT}/Frameworks/Simulator/." "${SRCROOT}/Frameworks/Active"
else
    cp -af "${SRCROOT}/Frameworks/Device/." "${SRCROOT}/Frameworks/Active"
fi

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


1

Моя відповідь охоплює наступні моменти:

  • Зробіть рамку, яка працює як для симулятора, так і для пристрою

  • Як експортувати “жирну” рамку какао-сенсорного сенсора (для обох симуляторів та пристроїв)?

  • Не визначені символи для архітектури x86_64

  • ld: символ (и) не знайдено для архітектури x86_64

Етапи 1: Спочатку побудуйте свої рамки за допомогою цілі Simulator

Етапи 2: Після успіху процесу побудови симулятора, тепер побудуйте для своєї рамки з вибором цілі пристрою або загальним вибором пристрою iOS

Крок 3: Тепер виберіть рамкову ціль і для цього в розділі "Фази збірки" виберіть "Додати сценарій запуску" та скопіюйте наведений нижче код сценарію)

Крок 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's directory

cp -R "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework" "${PROJECT_DIR}"


# Step 6. Convenience step to open the project's directory in Finder

open "${BUILD_DIR}/${CONFIGURATION}-universal"


Цей сценарій, здається, називає себе і таким чином викликає нескінченний цикл !! Довелося перезапустити комп'ютер після його запуску! Постійно породжували нові процеси xcodebuild ... і відкривали нові вікна пошуку - Буде голосувати
J.beenie

Ознайомтеся з відповіддю @ l0gg3r у цьому SO Q / A щодо аналогічного сценарію без проблеми з рекурсією.
J.beenie
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.