【问题标题】:Import Objective-c framework into Swift framework (Google Analytics + Cocoapod)将 Objective-c 框架导入 Swift 框架(Google Analytics + Cocoapod)
【发布时间】:2015-08-21 21:17:54
【问题描述】:

我正在尝试将我常用的 Swift 代码集中到一个框架中,其中部分代码使用了 Google Analytics。我将 Google Analytics 作为 Cocoapod 引入,但我无法像在原始项目中那样从新框架访问它,因为它是 Objective-C 并且框架中没有桥接头支持 [我正在使用 Swift 1.2]。

我通常在桥接头中的代码行是:

#import

我究竟应该把它放在我的项目中的什么地方,以使这一切都像以前在桥接头中一样工作?

我在Apple's documentation about mixing Swift and Objective-C 发现的是这样的:

从同一框架目标中导入代码

如果您正在编写一个混合语言框架,您可能需要访问 来自 Swift 的 Objective-C 代码和来自 Objective-C 的 Swift 代码。

将 Objective-C 导入 Swift

在相同的框架目标中导入一组 Objective-C 文件 您的 Swift 代码,您需要将这些文件导入 框架的 Objective-C 伞头。

将 Objective-C 代码从同一框架导入 Swift

在 Build Settings 下的 Packaging 中,确保 Defines Module 该框架目标的设置设置为是。在你的伞 头文件,导入您要公开的每个 Objective-C 头文件 迅速。例如:目标-C

导入

导入

导入

我认为最相关的短语是:

您需要将这些文件导入到 框架的 Objective-C 伞头

但是这个文件是什么以及如何创建它?

Apple 的文档前面提到(在表格中):

Objective-C 代码

导入 Swift

#import "Header.h"

好吧,我尝试创建一个文件“Header.h”并导入它,但这不起作用。我不知道他们想表达什么。我在构建设置中找不到任何“保护伞”。

所以我的问题是,如何在我的 Swift 项目中导入此文件 (#import ),以便它可以看到 Google Analytics cocoapod 框架,就像我通常在正常项目?

更新:

我开始相信可能objective-c 桥接头是与项目同名的.h 文件。我现在尝试在那里添加 import 语句,我得到的错误是:

!在框架模块“JBS”中包含非模块化标头

【问题讨论】:

  • 我也在为同样的事情苦苦挣扎——你有没有对它进行排序?
  • 还没有。由于这个问题,我一直在避免使用 cocoapods,但我在技术上使用的是 Google Analytics 的旧实现。我期待苹果会在某个时候意识到这个问题并采取一些措施。也就是说,除非已经有办法而且我只是不知道它是什么。
  • @John 您是否能够解决“在框架模块中包含非模块化标头”问题?我正在尝试做同样的事情(通过伞形标头将 GoogleAnalytics cocoapod 框架导入到 swift 框架中)并且我遇到了同样的错误。
  • @nebs 我相信是的。至少是进步。请参阅我的答案以获得解释。

标签: objective-c swift google-analytics frameworks cocoapods


【解决方案1】:

对于那些继续问我是否解决了这个问题的人,以下是我如何完成这个任务,将 KochavaTracker SDK Cocoapod 导入框架。该 SDK 目前是用 Objective-C 编写的。此答案基于 nuKs 提供的答案,具有这些具体步骤。

1) 在您的项目文件夹下创建一个名为 KochavaTracker 的文件夹,即 MyFramework/MyFramework/KochavaTracker。

2) 在该文件夹中创建一个名为 module.modulemap 的文件并插入以下内容:

/*
 This is the private module which is used to make private ObjC headers available to Swift code.
 Note how all header files need to be specified with paths relative to this file.

 This file lives inside a folder, and that folder is the actual module. In Xcode the SWIFT_INCLUDE_PATHS needs to include the parent directory to that folder.
 */
module KochavaTracker {
    header "../../Pods/KochavaTrackeriOS/KochavaTrackeriOS/Classes/KochavaTracker.h"
    export *
}

这有效地创建了一个模块,它是 SDK 接口的包装器,Swift 以后可以像导入其他 Swift 模块一样导入该模块。请注意,它依赖于 Pods 文件夹的相对路径。

3) 在构建设置中找到,修改您的 SWIFT_INCLUDE_PATHS 以包括:

$(SRCROOT)/KochavaTracker

这样您就可以导入模块,并将其定位在/作为您在其下创建的 KochavaTracker 文件夹中。

4) 酌情添加到您的 Swift 代码中:

import KochavaTracker

从那里您应该能够引用 KochavaTracker 模块中的类。

【讨论】:

  • $(SRCROOT)/MyFramework 应该是 $(SRCROOT)/KochavaTracker
  • 已编辑。谢谢@Wyetro
  • 如果MyFramework 也由 CocoaPods 管理怎么办?我应该编辑规范文件中的某些内容,而不是将 SWIFT_INCLUDE_PATHS 修改为 $(SRCROOT)/KochavaTracker
【解决方案2】:

解决方案不像应用程序那么简单。我们必须创建一个模块映射。

看看this example repo

在 Swift 代码中,我们只能导入所谓的模块。诀窍是定义一个模块,该模块又包含我们需要 Swift 代码访问的所有 ObjC 标头。

this article的模块图部分也可能对你有所帮助。

尽管桥接头很方便,但它有一个关键限制——你不能在框架项目中使用它。另一种方法是使用模块。

为此,请在您的项目目录中创建一个以您要使用的库命名的目录。我在 shell 中做了这个,在 Xcode 的支持下,将它命名为 CommonCrypto。在该目录中,创建一个封装库设置的 module.map 文件。对于 CommonCrypto,module.map 如下所示:

module CommonCrypto [system] { header "/usr/include/CommonCrypto/CommonCrypto.h" export * }

现在将新模块添加到项目设置中的 Swift Compiler – Search Paths 下的 Import Paths。在模块路径中使用 ${SRCROOT}(例如 ${SRCROOT}/CommonCrypto)以确保项目无论在何处签出都可以正常工作。

这使得在您的 Swift 文件中导入 CommonCrypto 成为可能。请注意,您使用此技术构建的任何框架的使用者也必须将模块添加到他们的 Swift 搜索路径中。

我按照上面文章中的程序,并以这种方式满足我的需要:

module Muse { header "Muse.framework/Headers/Muse.h" export * }

为了安全起见,我删除了 [system] lexon(因为它删除了警告),并将框架放在与 module.map 文件相同的文件夹中。

此外,如果需要,请不要忘记在您的框架目标中包含libc++.tbd 和其他必需的依赖项(在General 选项卡的Linked Frameworks and Libraries 部分中)。

【讨论】:

  • 它说“你使用这种技术构建的任何框架的消费者也必须将模块添加到他们的 Swift 搜索路径中。”。但是,如果我将我的框架作为二进制而不是源代码提供,我的用户如何将模块添加到他们的搜索路径中?。
【解决方案3】:

桥接头文件是使用Objective-C文件进入Swift框架的特定头文件。

您可以在Apple doc 中找到有关桥接的更多信息:

Xcode 将与您正在创建的文件一起创建头文件,并用您的产品模块名称命名它,然后添加“-Bridging-Header.h”。 (稍后您将在命名您的产品模块中了解有关产品模块名称的更多信息。)

所以你唯一要做的就是通过选择手动创建该文件

File > New > File > (iOS, watchOS, tvOS, or OS X) > Source > Header File.

如果你的框架名称是ABC,那么头文件的名称应该是:

ex : ABC-Bridging-Header.h

你可以把它放在你的框架项目中你想要的地方。

希望这可以帮助某人!

【讨论】:

  • 尝试在框架中执行此操作会生成此错误:“:0: error: using bridging headers with framework targets is unsupported.”
  • 我不明白这个问题。我的框架中有一个目标,但除此之外你指的是什么?
猜你喜欢
  • 2016-04-05
  • 1970-01-01
  • 1970-01-01
  • 2015-09-14
  • 1970-01-01
  • 2018-07-02
  • 1970-01-01
  • 2015-10-23
  • 2015-05-09
相关资源
最近更新 更多