写在前面: Swift 代码访问 Objective-C 代码,或者反之。导入外部框架时,请先确保 TARGETS --> Build Settings --> Packaging --> Defines Module 设置为 Yes。
在一个工程中导入一些 Objective-C 文件供 Swift 代码使用时,你需要依赖与 Objective-C 的桥接头文件(Bridging-Header)来暴露给 Swift。当你添加 Swift 文件到现有的 Objective-C 工程(或反之)时,Xcode 会自动提示是否创建桥接文件,点击Yes即可创建以 Bridging-Header 为后缀的桥接文件
注意:1.确保在 Build Settings
-> Objective-C Bridging Header 中设置桥接文件的自身真实路径(文件夹中的路径),而不是它所在的目录,如 工程名/桥接文件名。
2.TARGETS --> Build Settings --> Embedded Content Contains Code 设置为 Yes。
Swift 调用 OC :
1.在桥接文件中导入你需要使用的OC头文件,即可在整个工程下的Swift文件中用swift的语法使用OC的代码,就像使用系统自带的Swift类一样。
OC 调用 Swift :
1.在 swift 类名前加上 @objc 关键字 ,如果不行,在@objc后再加上 public 关键字。(我使用时单加一个 public 关键字是没有问题的)
2.在需要调用Swift的OC类中导入 #import "Product Mould Name -Swift.h",当这样导入提示:file not found 时,尝试将头文件改为: #import "Product Mould Name/Product Name -Swift.h" 。
Product Name 和 Product Mould Name 可以在工程下 TARGETS --> Build Settings --> Packaging 条目下找到,导入上面Swift.h 的头文件后可以使用工程下所有的Swift类,前提是要满足第1点。
CMD + 左键 点击进入Swift.h 的头文件,你会发现原有的被 public 修饰的 Swift 类已被自动编译成 OC的代码安静的躺在那里等你调用(如果已经在需要的类名前加上 public 修饰,还是没有发现那个类,请 CMD+B编译一下),需要调用Swift 的属性也是一样的道理。
为出现其他问题提供头绪,贴出来自haolloyin的问题解决提示:
- 把 Swift 和 Objective-C 文件看作相同的代码集合,并注意命名冲突。
- 如果你使用了框架,确保在
Packaging
下的Defines Module
编译设置被设置为Yes
。 - 如果你使用了 Objective-C 桥接头文件,确保 Swift 编译器中 Objective-C 桥接头文件的编译设置
Code Generation
有一个与项目相关的头文件的路径。这个路径必须是头文件自身的路径,而不是它所在的目录。 - Xcode 使用你的工程模块名,而不是以
target
的名称来命名 Objective-C 桥接头文件以及为 Swift 代码 自动生成的头文件。详见 Naming Your Product Module。 - 为了在 Objective-C 中可用, Swift 类必须是 Objective-C 类的子类,或者用
@objc
标记。 - 当你将 Swift 导入到 Objective-C 中时,记住 Objective-C 不会将 Swift 独有的特性转化成 Objective-C 对应的特性。详见列表 Using Swift from Objective-C。
- 如果你在 Swift 代码中使用你自己的 Objective-C 类型,确保先将对应的 Objective-C 头文件导入到你的 Swift 代码中,然后才将 Swift 自动生成的头文件导入到 Objective-C .m 源文件中来访问 Swift 代码。
- 用
private
修饰符标记的 Swift 声明不会出现在自动生成的头文件中。私有声明不会暴漏给 Objective-C,除非它们被明确标记有@IBAction
,@IBOutlet
或者@objc
等。 - 对于应用 targets 而言,如果有 Objective-C 桥接头文件时,被
internal
修饰符标记的声明会出现在自动产生的头文件中。 - 对于框架 targets 而言,只有被
public
修饰符标记的声明才会出现在自动生成的头文件中。你仍然可以在框架中的 Objective-C 部分使用被internal
修饰符标记的 Swift 方法和属性,只要它们声明所在的类继承自 Objective-C 类。关于访问级别修饰符的更多信息,请查看The Swift Programming Language中的访问控制(Access Control)