Проблемы со связыванием приложения iOS с пользовательским фреймворком
Я разбил большое iOS-приложение на несколько фреймворков и столкнулся со следующей проблемой:
Как правильно включить пользовательский проект Cocoa Touch Framework в проект приложения для iOS, чтобы все связывалось правильно?
- Я создал каркас проекта со всем необходимым кодом внутри.
- Чтобы проверить это, я создал образец рабочего пространства и добавил к нему проект фреймворка.
- Затем я создал пример проекта приложения для iOS с несколькими строками кода с использованием инфраструктуры и также добавил проект в рабочую область.
Теперь я перехожу к связующей части.
Первая попытка:
Откройте настройки цели приложения в XCode, выберите
Info
панели, и добавьте структуру вLinked Frameworks and Libraries
раздел.Чтобы все было хорошо, я также выбираю недавно добавленный фреймворк в проекте приложения и меняю его
Location
отRelative to Group
вRelative to Build Products
, Под местоположением показано как../Debug-iphonesimulator/MyFramework.framework
Текущая схема
<Simulator, Debug>
, Я ударилRun
и все работает как надо - приложение регистрирует, что оно использует фреймворк нормально.Теперь я очищаю папку сборки и меняю схему на
<Simulator, Release>
,Далее я ударил
Run
, проекты начинают сборку, а затем не удается связать приложение:
Undefined symbols for architecture x86_64: <a function from the framework> referenced from: <a file in the app>
,
После проверки папки сборки я вижу, что фреймворк был построен правильно, находится в .../Build/Products/Release-iphonesimulator/...
, и это толстый двоичный файл с i386 и x86_64 внутри.
Как мне следует правильно связать фреймворк, чтобы он работал в любой конфигурации (Debug, Release), и на симуляторе, и, конечно, на устройствах?
Чтобы уточнить, я намереваюсь разрабатывать как фреймворк (ы), так и приложение одновременно, поэтому такое решение, как, например, CocoaPods, делает это, предварительно однажды создавая толстые фреймворки, кажется не очень практичным (если я что-то упустил из-за отсутствие достаточного опыта работы с CocoaPods).
Ниже провал Link
фазовый выход:
Ld /Users/me/Library/Developer/Xcode/DerivedData/MyWorkspace-ahzqvfgoxbedpudjdhtqudgqzwba/Build/Intermediates/MyApp.build/Release-iphonesimulator/MyApp.build/Objects-normal/x86_64/MyApp normal x86_64
cd /some/where/here/lives/the/workspace
export IPHONEOS_DEPLOYMENT_TARGET=9.3
export PATH="/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin:/Applications/Xcode.app/Contents/Developer/usr/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin"
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++
-arch x86_64
-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator9.3.sdk
-L/Users/me/Library/Developer/Xcode/DerivedData/MyWorkspace-ahzqvfgoxbedpudjdhtqudgqzwba/Build/Products/Release-iphonesimulator
-F/Users/me/Library/Developer/Xcode/DerivedData/MyWorkspace-ahzqvfgoxbedpudjdhtqudgqzwba/Build/Products/Release-iphonesimulator
-filelist /Users/me/Library/Developer/Xcode/DerivedData/MyWorkspace-ahzqvfgoxbedpudjdhtqudgqzwba/Build/Intermediates/MyApp.build/Release-iphonesimulator/MyApp.build/Objects-normal/x86_64/MyApp.LinkFileList
-Xlinker
-rpath
-Xlinker @executable_path/Frameworks
-mios-simulator-version-min=9.3
-Xlinker
-objc_abi_version
-Xlinker 2
-fobjc-arc
-fobjc-link-runtime
-stdlib=libc++
-framework MyFramework
-Xlinker
-dependency_info
-Xlinker /Users/me/Library/Developer/Xcode/DerivedData/MyWorkspace-ahzqvfgoxbedpudjdhtqudgqzwba/Build/Intermediates/MyApp.build/Release-iphonesimulator/MyApp.build/Objects-normal/x86_64/MyApp_dependency_info.dat
-o /Users/me/Library/Developer/Xcode/DerivedData/MyWorkspace-ahzqvfgoxbedpudjdhtqudgqzwba/Build/Intermediates/MyApp.build/Release-iphonesimulator/MyApp.build/Objects-normal/x86_64/MyApp
Undefined symbols for architecture x86_64:
"SomeFancyFuncFromTheFramework()", referenced from:
-[AppDelegate application:didFinishLaunchingWithOptions:] in AppDelegate.o
1 ответ
Во-первых, создайте проект фреймворка iOS, обязательно установив Installation Directory
(INSTALL_PATH
) создать настройки для целевой платформы @rpath
, Я бы изменил схему Xcode, чтобы сделать ее общей. Теперь закройте каркасный проект, чтобы быть уверенным, что его можно открыть, когда мы импортируем его в проект приложения, выполнив следующие шаги.
Затем создайте проект iOS App. Как и вы, я создал App (Debug)
схема и App (Release)
схема. Я создал Frameworks
группа в проекте приложения, похожая на изображение, показанное ниже. Затем я нашел .xcodeproj
файл моего фреймворка, который я только что создал, и перетащил его в Frameworks
группа. Откройте раскрывающие треугольники, чтобы раскрыть рамочный проект Products
как показано на рисунке ниже. Перетащите его на Embedded Binaries
раздел в General
раздел цели приложения. Это должно автоматически добавить другие шаги, которые вы должны предпринять, чтобы заставить вещи работать должным образом (я считаю, что они включают добавление framewokr в качестве зависимости, связывание с фреймворком и копирование фреймворка во встроенное приложение).
Последний шаг - убедиться, что фреймворк может быть найден во время компиляции. В настройках сборки цели приложения обязательно установите Framework Search Paths
(FRAMEWORK_SEARCH_PATHS
) чтобы $(BUILT_PRODUCTS_DIR)
, Когда вы выбираете схему для приложения, которое создается в стиле сборки Develop, фреймворк будет построен в том же стиле сборки в том же каталоге, что и само приложение.