【问题标题】:handling dependencies for iOS Framework project处理 iOS 框架项目的依赖项
【发布时间】:2014-05-28 04:15:33
【问题描述】:

我使用这种方法创建了 iOS 框架项目:https://github.com/jverkoey/iOS-Framework

工作得非常整洁,但我有点困惑如何包含我的框架工作所需的库/框架,特别是如何做到这一点,以防万一使用我的框架的 3rd 方客户端应用程序可以包括这些库也没有冲突。

假设我的框架代码需要这两件事:

  • FacebookSDK.framework
  • libFlurry.a

第一个是 iOS 框架。当我将它添加到我的框架中的“使用库链接二进制文件”阶段并尝试编译使用我的框架的客户端项目时,链接器抱怨缺少符号 - 我需要将 FacebookSDK 添加到客户端项目中太好了:如果客户端应用程序想要使用 Facebook,则不会发生冲突。

但是,当我对 Flurry 静态库执行相同操作时,在编译客户端项目时出现重复符号错误。这让我有点困惑,因为 FacebookSDK.framework 不只是一个打包的静态库吗?

ukaszs-iMac:FacebookSDK.framework lukasz$ file Versions/A/FacebookSDK 
Versions/A/FacebookSDK: Mach-O universal binary with 3 architectures
Versions/A/FacebookSDK (for architecture i386): current ar archive random library
Versions/A/FacebookSDK (for architecture armv7):    current ar archive random library
Versions/A/FacebookSDK (for architecture cputype (12) cpusubtype (11)): current ar archive random library

所以我的问题是:

  1. 为什么嵌入在框架中的库(如 Facebook)没有链接到我的框架项目产品,而包含为 .a 文件的库是?
  2. 如何在我的框架中包含 .a 文件,以便在使用我的框架的客户端应用也需要此特定静态库时不会产生重复符号错误?

【问题讨论】:

    标签: ios frameworks linker static-libraries


    【解决方案1】:

    对于您描述的用例,您应该从您的应用程序链接到这些外部库,而不是您自己的框架。它可以是其中之一,但不能同时是两者。

    如果您决定这些依赖项属于应用程序的责任,您将从“Link Binary With Libraries”和任何其他显式链接配置中删除它们,并且只需使用这些框架和库的路径来投影您的框架项目,以便它可以在编译时找到符号(但不能链接到它们)(即库的路径应该包含在 LIBRARY_SEARCH_PATHS 中)。

    【讨论】:

    • 我想创建一个具有 Google Maps sdk 依赖项的框架。能否请您告诉我如何执行此操作的步骤。
    • @quellish 如果框架使用#import "FacebookSDK.h",则依赖项是从应用程序链接的。你将如何创建框架本身的二进制文件,因为它会因为 FacebookSDK 的未定义符号而失败。你能解释一下吗?
    【解决方案2】:
    1. 使用 cocoapods ,很简单 (http://cocoapods.org/)

    2. 您的应用程序开发人员必须包含 podfile 并下载依赖项。

    3. 在开发您的 SDK 时,使用 SDK 之上的参考应用程序/演示应用程序来模拟这一点。

    【讨论】:

    • 快速提问,试图弄清楚应用程序使用 2 个框架并且两个框架都使用共享库时的场景,这是构建应用程序时链接器的问题吗?
    • 不,我不这么认为,因为您只暴露了一个 pod 文件。
    • 不知道这个答案有多实用。确保它消除了框架开发人员的痛苦。你不能强迫你的框架的用户使用 cocoapods,特别是如果他们的应用程序正在使用其他依赖管理系统或者他们的应用程序已经存在了一段时间并且他们只是想包含你的框架来添加一个新的...跨度>
    • @rustylepord 你有这方面的教程吗?我想开发一个使用 FB SDK 的框架,我想将我的框架提供给我的供应商,一旦他们使用 cocoapods 安装了我的框架,它也应该安装 FB,因为它是一个依赖项。
    【解决方案3】:

    在构建框架时不应链接任何内容,只需使用框架对象创建一个 *.a 二进制文件即可。

    此外,您不应在框架中包含来自其他库的代码,因为客户端应用程序可能会直接添加相同的库或需要它们的不同版本,从而产生冲突。

    当然,您可以从框架中的其他库中引用 *.h 头文件来编译您的对象。

    因此,您的框架的安装步骤应详细说明所需的其他所需框架/库、其支持的版本、如何添加资源文件(如果有)等。这只是您可能要考虑创建的众多原因中的一部分CocoaPods' podspec 代替。

    【讨论】:

      【解决方案4】:

      您应该使用 CocoaPods。您可以通过链接 CocoaPod 来完成对 Facebook 的依赖。

      如果您想在您的 pod 中包含该特定版本的 Facebook,您可以将其放入您的存储库中并使用 vendored_frameworks 属性来引用它。

      同样,如果您想提供 libFlurry.a,您可以使用 s.vendored_libraries

      对于系统库,您不需要提供它们,例如libZ.a.

      我强烈建议使用pod lib create YourPodName 创建您的 CocoaPod。他们最近改变了它的工作机制,这真的很好。

      您可以创建一个示例项目,展示如何在应用程序的上下文中使用您的代码。

      然后是我刚刚学到的另一件事,有人可以pod try YourPodName,它会自动下载、集成和运行 Xcode 项目。

      CocoaPods 是值得的。

      【讨论】:

      • 对于大型框架(例如 Parse 和 Facebook)以及使用多个自定义开发 pod 时,我发现 CocoaPods 会减慢您的开发速度,因为它需要重新编译 SDK 的所有源代码以及您的代码.
      • @fatuhoku 实际上我最近一直在尝试为一些内部开发的 pod 解决这个问题。应该有一种方法可以利用 pod 规范,但不需要一直重新编译所有内容。还没想好。
      • @funroll 是否需要在我的 podfile 中包含代码,以便我可以链接到 pod?
      【解决方案5】:

      我正在使用 CocoaPods 构建我的框架项目。 该框架使用来自 CocoaPods 的一些第 3 个库。 Podfile 指定安装对框架目标的依赖。 当我构建框架时,它包含二进制文件中的所有库。

      如果我添加 use_frameworks!在 Podfile 中,构建框架时,它不会包含 3rd 方库。

      【讨论】:

      • 您好,Evan,我有同样的要求,并且使用了您上面对动态框架所说的相同步骤,它可以按预期编译和链接。现在我需要生成一个静态框架,其中包含二进制文件中的第 3 方库。我怎么做?为了构建静态框架,我刚刚将 Mach-O 类型更新为静态库,并且能够生成静态框架,但二进制文件没有 3rd 方库。
      【解决方案6】:

      使用 CocoaPods 依赖管理器。这是一个很好的指南,

      7 miniute video tutorial

      【讨论】:

        【解决方案7】:

        大多数情况下,如果您安装第三方框架,您可以使用 cocoapods 进行安装(这非常好,我肯定会这样做),或者他们会为您提供下载框架并将其包含在您的项目中。 如果您决定下载该库并将其包含在内,“入门”指南中通常会列出您需要的框架。

        意思是:让他们使用 cocoapods 安装并下载你的库,但不要包含任何其他内容,给他们列出他们需要的东西。

        【讨论】:

          猜你喜欢
          • 2012-02-04
          • 2012-12-21
          • 1970-01-01
          • 1970-01-01
          • 2010-09-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多