在xcode8

时间:2016-11-08 10:40:45

标签: ios objective-c swift xcode xcode8

我试图在没有运气的情况下参与混合的Swift和ObjectiveC项目。

我的项目由6个目标组成:

  • 应用
  • 核心
  • CoreTest
  • 摘要
  • WatchKit Extension
  • WatchKit App

我已经能够添加一个具有一个目标成员资格(App)的Swift类,并使用从 App-Bridging-Header.h 传递的ObjectiveC代码 " ObjectiveC到Swift代码"范式就像一个魅力。

相反,我正在努力使用Swift进入ObjectiveC代码"范例。 在特定情况下,我需要在ObjectiveC .m文件中使用一个新的Swift类,该文件是四个目标的成员。

我到目前为止所做的是:

  1. 将新的Swift文件添加到Core项目,指定四个成员资格(App,Core,Summary,WatchKit Ext)
  2. XCode要求为三个项目创建 -Bridging-Header.h Core,Summary和WatchKit Ext(App-Bridging-Header.h已经存在,因为之前已经使用过),我同意(不知道为什么它会在我添加我的Swift类的同一组文件夹中创建这些文件但是没关系)
  3. 我创建Swift类,在
  4. 之前添加 @objc
  5. 我去检查是否为所有模块设置了 Objective-C生成的接口标题名称,是的是
  6. 我会检查所有模块中定义模块是否设置为,并在主项目中设置为,是的是
  7. 我写下了所有四个目标的 -Swift.h 文件的导入
  8. 在我的Objective-C类中,我尝试使用我的新Swift类,显然它似乎工作(甚至自动完成)
  9. 我尝试构建项目,但未能说找不到 -Swift.h 文件
  10. 我已经关注了Mix and Match guide of Apple和许多SO主题,其中包括this one,这似乎显然是为了解决我的同样问题,但它并不起作用。

    还看过thisthis,但没有效果。

    还试图删除派生数据以及多次清理整个项目,但没有运气。

    编辑1:更多详情

    这是我的Swift类的声明     导入RealmSwift

    @objc class MyClass: Object {}
    

    这是在ObjectiveC

    中使用Swift类的片段
    MyClass *app = [[MyClass alloc] init];
    

    如果我避免使用#import ...- Swift.h,则构建失败,说我正在使用未声明的识别符#34; 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标头的导入集。 我使用相对Build Settings属性中指定的模块名称。请注意,有人有' _'自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文件的交叉可见性

    我尝试过以下方法:

    • 仅在目标应用
    • 中添加了Swift类
    • XCode创建了“桥接标题”
    • 插入#import" ProjectName_App-Swift.h"在仅由App
    • 使用的ObjectiveC文件中
    • 在此文件中使用Swift类
    • 编译!我能够使用Swift类

    当为多个目标定义Swift类并且这些多个目标使用ObjectiveC文件时,它不起作用。构建错误是这样的:目标X - > " ProjectName_TargetY-Swift.h"文件未找到。 好像目标无法看到其他目标-Swift.h文件。

    我做错了什么? 谢谢你的帮助

10 个答案:

答案 0 :(得分:41)

我在编辑4中做出的假设证明是正确的。 如果一个项目有多个目标,那么" -Swift.h"文件不能全部导入.m ObjectiveC文件。

因此,必须采用一种解决方案,即更改 SWIFT_OBJC_INTERFACE_HEADER_NAME 构建设置,并使其在不同目标中保持相同。 为此,请将 $(SWIFT_MODULE_NAME)-Swift.h 生成此属性的指令更改为 $(PROJECT_NAME)-Swift.h ,如解释here < / p>

  

也可以将Build Settings中的Product Module Name设置在模块中设置为相同(我将其设置为$(PROJECT_NAME)),以便生成的-Swift.h文件具有相同的名称跨所有模块。这消除了添加/检查预处理器宏的需要。

按Alt键进入产品菜单后执行此清洁构建文件夹。由于标题的名称现在在目标之间共享,因此可以在.m ObjectiveC文件中导入一次,并且所有目标都可以从Swift类中受益。

如果在构建之后仍然显示错误,请确保通过Cmd单击其名称可以从XCode到达标头。它应该打开一个包含类似于此代码的文件:

SWIFT_CLASS("_TtC27ProjectName_Summary11MyClass")
@interface MyClass : NSObject
- (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;
@end

如果需要确保生成这些标头,请打开终端并使用此命令

find ~/Library/Developer/Xcode/DerivedData -name "*Swift.h"

您应该看到每个目标的一个标题

在这些更改之后发生在我身上的另一个问题是它开始在我没有触及的ObjectiveC代码上给出错误。问题是由于导入的位置,如报告here

  

正好在.m文件的顶部你#import隐藏的桥接头可以有所作为。通常的麻烦的迹象是你得到一个“未知类型名称”编译错误,其中未知类型是在Objective-C中声明的类。解决方法是在#import隐藏的桥接头之前,#import导入包含Objective-C文件中未知类型声明的.h文件。必须这样做可能会令人烦恼,特别是如果有问题的Objective-C文件不需要知道这个类,但它解决了问题并允许继续编译。

最后,代码在设备和模拟器上编译并运行!

答案 1 :(得分:7)

我的解决方案是通过<>语法导入生成的swift标头:

#import <OtherTargetWithSwiftClass/OtherTargetWithSwiftClass-Swift.h>

答案 2 :(得分:5)

这不是问题的解决方案,但由于很多人可能会在此页面上找到找不到<ModuleName>-Swift.h文件的问题(就像我一样)我想补充一个可能的原因:

当swift文件中存在编译器问题时,Xcode可能无法生成标头,因此文件丢失。

至少在我的情况下,一旦我修复了Swift文件中的编译错误,<ModuleName>-Swift.h not found就消失了。

答案 3 :(得分:2)

我有类似的问题,几乎最终花了一整天的时间来解决问题,同时遵循其他开发人员关于StackOverflow和其他一些来源的建议。

我正在从Xcode 7.3.1升级到Xcode 8.2.1,从Swift 2.2升级到Swift 3.0.1 就我而言,我发现PROJECT_NAME-Swift.h文件未在以下位置创建:

~/Library/Developer/Xcode/DerivedData/PRODUCT-NAME-hdkrxixrxbiorwesffpqvefxsrzl/Build/Intermediates/PRODUCT-NAME.build/Debug/PRODUCT-NAME.build/Objects-normal/x86_64/PRODUCT-NAME-Swift.h.

我猜它以某种方式试图从上面的路径引用这个头文件,因此错误。我手动复制了它。在此之后没有做干净的构建。 这解决了我的问题,swift头文件开始被创建用于进一步的编译和构建。

答案 4 :(得分:1)

我在一个有 iOS ApplicationSubModule Framework 的项目中遇到了这个问题,

当我将框架构建配置改为 RELEASE 时出现问题

答案 5 :(得分:1)

如果此页面上的建议解决方案均无效,则最好检查一下您的框架目标中的配置。如果您在主应用程序中创建自定义配置,您希望框架目标中也存在相同的配置。如果这些不匹配,则可能会导致 Xcode 无法找到正确的构建设置,从而无法找到正确的头文件。

答案 6 :(得分:0)

对于我的情况,它在Xcode 8中运行正常但是带有

的文件
#import "Project-Swift.h"

缺少LucioB描述的进口

使用 Xcode 9 可消除这些错误

答案 7 :(得分:0)

就我而言,我有一个工作区,其中包含iOS应用子项目,框架子项目和CocoaPods Pods子项目。我的框架子项目中发生了“ModuleName-Swift.h文件未找到”错误,因为该文件尚未由Pods子项目创建。

我不确定是否有办法告诉Xcode子项目之间的依赖关系,但我只是在左侧的Project Navigator中重新排序它们:

  1. 框架
  2. iOS应用
  3. 之后工作得很好!

答案 8 :(得分:0)

就我而言,我将导入语句声明为.h文件

然后我更改

#import "ProjectName_App-Swift.h"

放入实施文件(.m)

清理并重新启动Xcode 工作中

答案 9 :(得分:0)

我在模块化应用程序中开发,-Swift.h 是 ModuleName-Swift.h

我删除了派生数据,清理了构建文件夹,重新启动了我的 mac,但解决的是:

pod cache clean ModuleName

之后

run pod update ModuleName