如何全局导入一个Swift框架?

57
我希望有一种方法可以在每个类中全局导入我的Swift Cocoapods,我该如何实现?
我尝试了很多方法,但它们都没有起作用。以下是我尚未尝试并且认为如果找到方法可以工作的一些方式:
像导入UIKit一样拥有一个通用的导入语句并将所有内容放在其中。(编辑:失败)
以某种方式将Swift框架放入Obj-C bridging header中并在其中导入内容。

是的,使用桥接头文件。这个问题可能是重复的:https://dev59.com/N4rda4cB1Zd3GeqPP7VB。 - prolfe
1
实际上,显然那个答案从未被接受,所以可能行不通...我认为答案可能是你不能在Swift中这样做。抱歉,你需要在使用框架的每个文件中导入。 - prolfe
OP,是什么阻止你接受这个答案呢? @prolfe 不幸的是,没有绕过这个问题的方法,但这是正确的方式 - 代码只在需要的地方可用,因此可以更快地编译/运行所有内容。 - Krodak
人们对这个问题很感兴趣,我仍然认为/希望有某种方法来获得这种行为。 - Esqarrouth
6个回答

58

在导入之前添加 @_exported 可以使其全局导入。

@_exported import MyPodModuleName

然而,像其他答案提到的那样,为整个模块这样做并不推荐,因为它会在模块之间引入隐式耦合。

因此,最好尝试像这样:

import Foundation

@_exported import class MyModuleName.MyClassName
@_exported import class MyModuleName.MyOtherClass

1
但是我该如何在项目中编写...像AppDelegate或任何视图控制器一样。 - Maulik shah

46

在Swift中强烈不建议这样做,因为这会在模块之间引入隐式耦合关系。

不过,你可以通过在导入其他模块的模块中声明typealias来使某个符号全局可用:

import ModuleName
public typealias ClassName = ModuleName.ClassName

12
理论上,100%松耦合的组件只是存在于理论中,项目总有一些全局库依赖。例如具有日志级别的自定义记录器即为良好示例。因此,typealias 在这种情况下非常适用。请注意不要改变原文意思。 - Centurion
我曾经做过上述操作,但不得不转而使用 @_exported,因为 Swift 的编译错误——尝试使用 Cuckoo 库的“Mock”功能并返回类型别名,你就能理解我的意思了。 - Top-Master

19

截至Swift4:

  • 在一个Swift项目中
  • 想要全局引入另一个使用cocoapods的Swift项目

我刚刚通过在我的桥接头文件中添加以下行来实现:

#import <PodName/PodName-Swift.h>

这种做法好坏难以确定,但我只是想让我的项目全局可用一些扩展。这个方法解决了问题。


2
有趣的“hack”是在桥接头文件中导入自动生成的.h文件。但有一个限制,即.h文件仅包括Swift模块中的@objcNSObject子类;它不包括纯Swift的内容。 - samwize

8

这是无法做到的。而且这不是一个错误,这是一种语言特性(至少在 Swift 2.2 中是这样的)。

Swift 使用模块(苹果在 Xcode 5 中引入了它们用于 Objective-C),每个文件都是一个语义单元,因此您需要明确告知 Xcode 哪些模块被暴露给定义的文件。

不仅不存在对所描述行为的支持,而且也不应该试图绕过它。使用不必要的(未使用的)模块理论上可能会产生更慢的代码(考虑到编译器将此信息用于其优化过程)。


此外(或“随机地”),Xcode 可能会神奇地为您的 Swift 文件获取一个框架的知识,但是 AppCode 将完全困惑。您需要在框架客户端的每个 Swift 文件上执行 import - Dan Rosenstark
@Krodak,你有苹果官方链接提到这个问题吗?我非常同意你的观点,但我真的希望能从苹果得到某种形式的指示。谢谢。 - Julian Osorio

3
您可以通过以下方式手动实现相同的功能:
  • 创建Objective-C Bridging Header file
  • #import <UIKit/UIKit.h>添加到Objective-C Bridging Header文件中(这样您就不需要为每个.swift文件重复此操作)。
对于pods,您需要执行以下操作:#import <SwiftyJSON/SwiftyJSON-umbrella.h>

0
一个不想这样做的原因是:
想象一下,如果你的框架都使用相同的方法名,那么编译器会对此感到困惑。编译器无法确定应该运行哪个方法。
要了解更多,请参见 this 问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接