【发布时间】:2017-03-21 22:56:09
【问题描述】:
我正在尝试处理一个混合的 Swift 和 ObjectiveC 项目,但没有运气。
我的项目由 6 个目标组成:
- 应用
- 核心
- 核心测试
- 总结
- WatchKit 扩展
- WatchKit 应用程序
我已经能够添加一个具有一个目标成员资格 (App) 并使用从 App-Bridging-Header.h 传递的 ObjectiveC 代码的 Swift 类 “将 ObjectiveC 转换为 Swift 代码”范式就像是一种魅力。
相反,我正在为“Swift into ObjectiveC 代码”范式而苦苦挣扎。 在特定情况下,我需要在作为四个目标成员的 ObjectiveC .m 文件中使用新的 Swift 类。
到目前为止,我一直在做的是:
- 向 Core 项目添加一个新的 Swift 文件,指定四个成员(App、Core、Summary、WatchKit Ext)
- XCode 要求为三个项目 Core、Summary 和 WatchKit Ext 创建 -Bridging-Header.h(App-Bridging-Header.h 已经存在,因为它以前使用过),我同意(不知道为什么它会在我添加 Swift 类的同一组文件夹中创建这些文件,但没关系)
- 我创建了 Swift 类,在 class 之前添加了 @objc 键
- 我去检查是否为所有模块设置了Objective-C Generated Interface Header Name,是的
- 我去检查Defines Module是否在所有模块中设置为No,并在主项目中设置为Yes,是的
- 我记下了所有四个目标的 -Swift.h 文件的导入
- 在我的 Objective-C 类中,我尝试使用我的新 Swift 类,显然它似乎可以工作(甚至是自动完成)
- 我尝试构建项目,但提示找不到 -Swift.h 文件
我关注了 Mix and Match guide of Apple 和许多 SO 线程,包括 this one,这些线程似乎可以解决我的相同问题,但它不起作用。
也尝试过多次删除派生数据以及清理整个项目,但都没有成功。
编辑 1:更多细节
这是我的 Swift 类的声明 导入 RealmSwift
@objc class MyClass: Object {}
这是ObjectiveC中Swift类的使用sn-p
MyClass *app = [[MyClass alloc] init];
如果我避免使用 #import ...-Swift.h,则构建失败,说我正在使用未声明的标识符“MyClass”,这是合理的。
如果我确实使用 #import ...-Swift.h 文件,它会说模块 X 找不到模块 Y 等等。
编辑 2:Swift 模块名称
通过查看每个目标的 SWIFT_OBJC_INTERFACE_HEADER_NAME 属性,我发现它是使用这种语法 $(SWIFT_MODULE_NAME)-Swift.h 构建的,我是否需要更改SWIFT_MODULE_NAME 到 MODULE_NAME?
编辑 3:进口
这是 .m ObjectiveC 文件中 Swift 标头的导入集。 我正在使用相关构建设置属性中指定的模块名称。请注意,由于 WatchKit 扩展目标在目标名称中有一个空格,因此其中包含 '_' 字符。
#import "ProjectName_App-Swift.h"
#import "ProjectName_Core-Swift.h"
#import "ProjectName_Summary-Swift.h"
#import "ProjectName_WatchKit_Extension-Swift.h"
编辑 4:-Swift.h 文件的交叉可见性
我尝试了以下方法:
- 仅在目标 App 中添加了 Swift 类
- XCode 创建了桥接头
- 在 ObjectiveC 文件中插入了#import "ProjectName_App-Swift.h",仅供 App 使用
- 在这个文件中使用了 Swift 类
- 它编译!而且我可以使用 Swift 类
当为多个目标定义 Swift 类并且这些多个目标使用 ObjectiveC 文件时,它不起作用。构建错误是这样的: Target X -> "ProjectName_TargetY-Swift.h" file not found。 好像一个目标看不到其他目标 -Swift.h 文件。
我做错了什么? 感谢您的帮助
【问题讨论】:
-
你能编辑你导入 Swift 生成的标头的方式吗?
-
@Sealos 将导入添加到原始问题
-
我相信您在标头导入中缺少项目名称。你介意检查一下吗?像这样:“Project_name_WatchKit_Extension-Swift.h” 另外,您可以检查文件在 swift 文件中执行 SomeClass.classForKeyedUnarchiver 的模块并获取它。
-
我相信你说的是真的,你不能将其他目标快速导入到不同的目标中。您需要做的是将 Swift 文件添加到目标成员资格(例如:i.stack.imgur.com/v3Z0A.jpg)。那应该可以解决您的问题!
-
@Sealos 谢谢,我发现它与我在编辑 4 中发现的问题有关,我首先尝试了您的解决方案,但没有成功。不过谢谢你帮助我
标签: ios objective-c swift xcode xcode8