将iOS应用与自定义框架相关联的问题

时间:2016-07-22 20:26:02

标签: xcode ios-frameworks

我将一个较大的iOS应用程序分成几个框架,我面临以下问题:

如何将自定义Cocoa Touch框架项目正确地包含到iOS应用程序项目中,以便一切正常链接?

  1. 我创建了一个项目框架,里面包含了所有必要的代码。
  2. 为了测试,我创建了一个示例工作区,并将框架项目添加到其中。
  3. 接下来,我创建了一个示例iOS应用程序项目,使用框架使用几行代码,并将项目添加到工作区。
  4. 现在,我到达链接部分。

    首次尝试:

    1. 在Xcode中打开应用目标设置,选择Info窗格,然后在Linked Frameworks and Libraries部分添加框架。

    2. 为了让事情变得更好,我还在应用项目中选择了新添加的框架,并将LocationRelative to Group更改为Relative to Build Products。该位置下方显示为../Debug-iphonesimulator/MyFramework.framework

    3. 目前的方案是<Simulator, Debug>,我点击Run一切正常 - 应用程序记录它正在使用框架

    4. 现在,我清理构建文件夹,并将方案更改为<Simulator, Release>

    5. 接下来,我点击Run,项目开始构建,然后应用链接失败

    6. 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
      

1 个答案:

答案 0 :(得分:1)

首先,创建iOS框架项目,确保将框架目标的Installation DirectoryINSTALL_PATH)构建设置设置为@rpath。我会改变Xcode方案,使其成为共享方案。现在关闭框架项目,确保在我们按照以下步骤将其导入App项目时可以打开它。

接下来,创建iOS App项目。与您的方式类似,我创建了App (Debug)方案和App (Release)方案。我在App项目中创建了一个Frameworks组,类似于下面显示的图像。然后我找到了我刚创建的框架的.xcodeproj文件,并将其拖到Frameworks组中。打开显示三角形以显示框架项目的Products,如下图所示。将其拖到应用目标的Embedded Binaries部分的General部分。这样做应该会自动添加您需要采取的其他步骤才能使事情正常工作(我相信这些步骤包括将framewokr作为依赖项添加,链接到框架,并将框架复制到构建的应用程序中)。

enter image description here

最后一步是确保在编译时可以找到框架。在应用目标的构建设置中,请务必将Framework Search PathsFRAMEWORK_SEARCH_PATHS)设置为$(BUILT_PRODUCTS_DIR)。当您为使用Develop构建样式构建的应用程序选择方案时,该框架将在与应用程序本身相同的目录中以相同的构建样式构建。