我将一个较大的iOS应用程序分成几个框架,我面临以下问题:
如何将自定义Cocoa Touch框架项目正确地包含到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的胖二进制文件。
我应该如何继续正确链接框架,以便它可以在任何配置(调试,发布)以及模拟器,当然还有设备上工作?
为了澄清,我打算同时开发框架和应用程序,因此可以使用例如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
答案 0 :(得分:1)
首先,创建iOS框架项目,确保将框架目标的Installation Directory
(INSTALL_PATH
)构建设置设置为@rpath
。我会改变Xcode方案,使其成为共享方案。现在关闭框架项目,确保在我们按照以下步骤将其导入App项目时可以打开它。
接下来,创建iOS App项目。与您的方式类似,我创建了App (Debug)
方案和App (Release)
方案。我在App项目中创建了一个Frameworks
组,类似于下面显示的图像。然后我找到了我刚创建的框架的.xcodeproj
文件,并将其拖到Frameworks
组中。打开显示三角形以显示框架项目的Products
,如下图所示。将其拖到应用目标的Embedded Binaries
部分的General
部分。这样做应该会自动添加您需要采取的其他步骤才能使事情正常工作(我相信这些步骤包括将framewokr作为依赖项添加,链接到框架,并将框架复制到构建的应用程序中)。
最后一步是确保在编译时可以找到框架。在应用目标的构建设置中,请务必将Framework Search Paths
(FRAMEWORK_SEARCH_PATHS
)设置为$(BUILT_PRODUCTS_DIR)
。当您为使用Develop构建样式构建的应用程序选择方案时,该框架将在与应用程序本身相同的目录中以相同的构建样式构建。