不是在Xcode 6中创建的Swift到Objective-C头

Swift to Objective-C header not created in Xcode 6

我最近一直在努力将Swift添加到一个现有的项目中,以便以现实世界的方式进行尝试。

在将Swift源文件添加到项目中时,我对于获取"桥接头文件"没有问题,也就是说,从Objective-C到Swift。

但是应该公开标记为@objc的swift类或objc类的子类的*-Swift.h头文件却找不到:-(

我没有看到任何关于如何在我的主应用程序代码(仍然是Objective-C)中使用我的新子类(用swift编写)的具体说明。

我是该应用程序的主要开发人员,它有相当大的代码库(70.000行),因此一次性转换它是不可能的。


现在它起作用了。

  • 项目必须具有不包含空格的产品模块名称。
  • 在"生成设置"中的"打包"下,"定义模块"必须设置为"是"。
  • 终于奏效了。感谢大家的帮助:—)


    我有一个类似的问题,发现你只能

    #import"ProductModuleName-Swift.h"

    到obj-c.m文件,而不是找到伞头的.h文件


    我发现在生成文件之前必须修复所有生成错误。

    对我来说,问题在于这是一个鸡/蛋的问题,在我真正评论了#import声明之前,我没有看到任何构建错误:

    //#import"ProductModuleName-Swift.h"

    它显示了我的swift代码中的许多其他错误。

    一旦我修复了这些新错误并成功地构建了源代码,我就取消了对#import和bingo的注释!头已创建并正确导入:)


    如果项目模块名称中有空格,则必须用下划线替换空格。

    例如,如果您的项目名称是"我的项目",您将使用:

    #import"My_Project-Swift.h"


    如果你像我一样,你可能把标题名搞错了。在敲打了我的头一段时间后,我在DerivedData中查找了文件,确信它就在那里。在我的设置中(使用标准派生数据文件夹,我相信):

    1
    2
    cd ~/Library/Developer/Xcode/DerivedData
    find * -iname '*Swift.h'

    会找到它的。如果该文件夹中没有匹配的内容,则Xcode不会生成它。

    我用的是Xcode 6.2(6C86E)


    *唯一重要的是:*

    在目标中使用定义的"产品模块名称",后跟-swift.h

    1
    2
    3
    4
    #import <Product Module Name>-Swift.h

    // in each ObjectiveC .m file having to use swift classes
    // no matter in which swift files these classes sit.

    无论"定义模块"参数设置为是或否,还是未设置"产品模块名称"项目。

    提示:SWIFT类必须从NSObjor派生出来,或者用@ Objc属性加标签,以便暴露于ObjvEc/Field[COCGA…


    我想再添加一个您可能会发现这个问题的原因-我正在创建一个混合了swift和objective-c代码的框架。我无法在框架外导入swift类-我检查了-swift.h文件,它正在生成,但是是空的。

    问题是非常非常简单的——我没有公开我的任何一个速成班!一旦我向类中添加了public关键字,我就能够从框架内部和外部的类中使用它们。

    另外需要注意的是,在框架内(在.m文件中,只有另一个答案提到),我必须将-swift.h文件导入为:

    1
    #import <FrameworkName/FrameworkName-Swift.h>


    我也有同样的问题。似乎在添加第一个swift文件之前,您必须调整设置(定义模块和产品模块名称)。

    如果您随后执行此操作,则不会为此项目生成"*-swift.h"文件,即使您添加了更多的swift文件或删除了swift文件并创建了一个新文件。


    文件名前面总是有目标名。它被称为产品名称,但实际上它是目标名称。因此,如果您希望它为一个新的目标而构建,那么就要准备好预期的that_target-Swift.h文件。

    解决这个问题的方法之一是

  • 为每个目标添加一个预处理器,该预处理器是目标本身的名称(不带空格)。如MY_TARGET=1。为每个目标在项目设置->生成设置->预处理器宏中添加此项。
  • 如果您使用的是PCH文件,
  • 在PCH文件中添加这些行

    1
    2
    3
    4
    5
    #if MY_TARGET==1
    #include"My_Target-Swift.h"
    #elif THAT_TARGET==1
    #include"That_Target-Swift.h"
    #endif

    使用PCH文件的优点是不必在任何地方都包含头文件。

  • 如果不使用PCH文件,只需在单个头文件中添加这些相同的行,并在需要使用Swift类的任何位置包含该头文件。
  • 这应该很管用。


    这里是modulename swift.h的另一个变体,未生成。

    我决定在我的项目中包含iOS图表,但不想将源代码混合在同一个目录中,所以我将图表项目文件夹放在代码的项目文件夹旁边。我将Charts项目拖到我的项目的导航栏中,并将框架包含在我的项目目标的嵌入二进制文件列表中的常规项目设置中,并在我的项目的"生成选项"部分的"生成设置"选项卡中将嵌入内容"包含swift代码"切换为"是"。

    我的项目的modulename swift.h文件将永远不会生成,无论这里建议什么其他开关或设置。最后,使用Louz查找-swift.h文件的方法,我发现在charts.framework/headers中项目的xcode build目录的深处生成了一个charts swift.h文件。/

    使用Daniel Gindi的iOS Charts Swift软件包而不在我的项目源目录中包含代码的解决方案是添加:

    1
    #import"Charts/Charts-Swift.h"

    到绘制项目数据的模块。


    请允许我分享我在旧objc项目中使用swift的经验。我不必把Defines module设为YES

    在我的例子中,我需要手动确保有一个objc桥接头。我的生成设置中只存在生成的接口头名称。

    Missing bridging header

    这将导致生成myapp swift.h文件,但没有我的swift类的任何痕迹。

    Apple文档说,在添加第一个swift文件时,将提示您创建一个桥接头文件。嗯,我没有。我手动添加了一个MyApp-Bridging-header.h文件,并在"objective-c桥接头"字段中指向它。这使得我的myapp swift.h文件中充满了我的swift类。

    单据:导入Swift到Objective-C


    如果Xcode实际上正在生成-swift.h头文件(Deep-Inside-DerivedData),但它没有引用您的swift类,请确保您还定义了一个桥接头文件。我阅读文档的方式暗示我只需要从Swift调用Objective-C,但似乎也需要从Objective-C调用Swift。

    请看我的答案:https://stackoverflow.com/a/27972946/337392

    编辑:这是因为公共和内部访问修改器,正如我在Apple文档中最终发现的那样:

    By default, the generated header contains interfaces for Swift
    declarations marked with the public modifier. It also contains those
    marked with the internal modifier if your app target has an
    Objective-C bridging header.


    附议了很多人在这里,但增加了一个相关的屏幕截图。swift和obj-c代码当然可以共存。这不是一场全无的比赛。

    要访问Objective-C中的swift文件,只需将此调用添加到obj-c文件中(在.m/实现文件中):

    1
    #import"{product_module_name}-Swift.h"

    (其中产品模块名称表示项目的产品模块名称)。与其猜测产品模块的名称,或者用空格和特殊字符找出角落的大小写,不如转到项目中的"构建设置"选项卡,然后键入"产品模块名称"-检查员将向您展示您的产品模块名称。我的是我没想到的。如果你不明白的话,看看这个屏幕截图。

    enter image description here

    为了让obj-c代码在swift中工作,您只需要添加一个桥接头文件并在那里导入相关的obj-c头文件。


    好吧,这是你真正需要的东西!

    1.删除您添加的所有swift文件,编译代码,没有任何错误。

    ----------

    enter image description here

    ----------

    2.转到"项目"生成设置,并设置产品模块名称。项目必须具有不包含空格的产品模块名称。

    ----------

    enter image description here

    ----------

    3.在构建设置、打包下、项目中,必须将"定义"模块设置为"是",而不是"目标"!

    ----------

    enter image description here

    ----------

    4.现在在文件->新建文件->中创建一个swift文件或视图控制器。

    ----------

    enter image description here

    ----------

    它将要求创建一个桥接头,允许它创建一个。如果您拒绝过一次,则必须手动添加桥接头.h

    5.在控制器中添加@objc,告诉编译器有一些swift文件需要向objectec公开。

    ----------

    enter image description here

    ----------

    6.建立项目并在任何一个目标控制器中导入import"-swift.h",它将起作用!您可以命令单击它来查看实际文件!

    ----------

    enter image description here

    ----------

    希望这有帮助!


    最重要的是这个文件是不可见的!!!!至少它在xcode6 beta5中。在您的工作区中将没有名为"yourmodule swift.h"的文件。只需确保您有模块名并将模块定义为是,然后在Objective-C类中使用它。


    这个答案解决了一个用例,在这个用例中,您可能已经有了一些调用swift类的Objective-C代码,然后开始接收这个错误。

    如何解决问题

    以下步骤最终为我解决了所有问题。我在上面读到有人提到"鸡和蛋",正是这个概念引导我进入了这个过程。这个显式的过程表明,必须删除引用swift类的任何Objective-C代码,直到生成头之后。

  • 注释掉中的import"productmodulename swift.h"语句您的目标C实现文件
  • 对目标C实现文件中的任何引用进行注释,以便斯威夫特班
  • 清理和生成
  • 解决所有错误/警告
  • 删除对import"productmodulename swift.h"语句的注释
  • 清除和生成(成功或修复任何剩余错误,请验证此时您没有引用Objective-C中的任何Swift类。如果是的话,暂时把这些评论掉)
  • 确认"productmodulename swift.h"是由命令单击生成的关于import"productmodulename swift.h"语句的类名
  • 删除Objective-C实现文件中引用swift类的代码注释。
  • 正常清理和生成("productmodulename swift.h"应为生成并引用swift类的目标C代码可以正常使用
  • 注意:在执行此过程时,有关将空格改为下划线和将"定义"模块改为"是"的答案仍然适用,Apple文档中指定的规则也是如此。

    桥接头路径

    在一个错误中,在生成过程中找不到文件productmodulename bridging header.h。这个事实产生了一个错误

    < unknown>:0: error: bridging header
    '/Users/Shared/Working/abc/abc-Bridging-Header.h' does not exist

    仔细检查错误表明,文件永远不会存在于描述的位置,因为它实际上位于(错误的路径)

    '/users/shared/working/abc/abc/abc桥接头.h'。快速搜索目标/项目生成设置以手动进行更正,并再次自动生成abc swift.h文件。

    build-settings


    您必须在Objective-C类中导入一个头,它是:

    1
    #import"ProductModuleName-Swift.h"

    它是自动生成的,在引用中它说"目标中的任何swift文件都将在包含此导入语句的objective-c.m文件中可见"。


    未创建项目中的实际文件([ProductModuleName]-Swift.h)。cmd+单击导入,或者动态地(在内存中)生成它,这样您就可以看到链接是如何完成的,或者在某个Xcode缓存目录中的某个位置打开一个文件,但它不在项目目录中。

    您需要将defines module project prop(在目标的生成设置中)设置为yes,如果您的模块名有空格或破折号,请在[productmodulename]-swift.h文件的所有导入中使用。

    您可以在所有使用swift类型的.h和.m文件中导入它,也可以在.pch中导入它。

    因此,如果我的模块(项目)命名为"测试项目",我将像这样导入到我的项目的.pch文件中(就在那里):

    1
    #import"Test_Project-Swift.h"

    项目必须具有不包含空格的模块名。在"生成设置"中的"打包"下,"定义模块"必须设置为"是"。对导入语句进行了注释:

    如果导入"productmodulename swift.h"时仍有错误,则

    //#导入"productmodulename swift.h"

    它显示了我的swift代码中的许多其他错误。

    一旦我修复了这些新错误并成功地构建了源代码,我就取消了对导入和宾果的注释!头已创建并正确导入:)


    只需提醒在那里项目名中使用"."的任何人。对于桥接头文件的swift版本,xcode将用下划线"_uuu"替换"."。奇怪的是,生成的桥接头.h不会用下划线替换句点。

    例如,名为my.project的项目将具有以下桥接头文件名。

    桥接头.h(自动生成)

    my.project桥接头.h

    斯威夫特

    MyoPay.h

    我希望这能帮助那些用了一段时间却像我一样陷入困境的人。此文件可在以下位置找到。

    macintosh hd/users/user/library/developer/xcode/deriveddata/my.project-fntdulwpbzdbkhanemcrfil/build/intermediates/my.project.build/debug-iphoneSimulator/my.project.build/derivedsources

    当心,

    乔恩


    我发现了一个对我有用的诀窍。

  • 在appdelegate.h文件和productName-prefix.pch文件中创建import"productmodulename swift.h"。如果在Xcode6中没有它,那么可以用这种方式创建它,为什么在Xcode6中不自动创建projectname-prefix.pch?
  • 如果收到关于"productmodulename swift.h"的错误,命令+shift+k清除代码,请将其从appdelegate.h文件中删除。
  • 再次清除代码。现在一切都会很有魅力
  • 如果您再次收到关于"productmodulename swift.h"的错误,请在appdelegate.h文件中再次创建并再次清除代码。
  • 每次收到此错误时都要执行此操作(从appdelegate.h文件中删除并创建"productmodulename swift.h",然后清除代码),使其保持安静。


    我找到了这个解决方案

    • 创建swiftbridge.h
    • 输入"productmodulename swift.h"
    • 将此.h文件设为公共文件(重要),在"显示文件检查器(右栏)"->中选择"将其设为公共文件"

    现在你可以

    1
    #import"SwiftBridge.h"

    而不是productmodulename swift.h

    这是一个解决方案,对于下一个版本的Xcode,我认为这个问题将得到解决。祝你好运


    我很难确定我的模块名/目标-C导入了Swift的报头。我也读了很多文章。

    但是项目名称及其所有包含的特殊字符(无论是"."或数字或空格)的最终答案-您可以在目标的构建设置下的"产品模块名称"中找到适合您的文本。

    例如,我的目标名称以一个数字"1毫克"开头,上面提到的字段显示"毫克"作为我的模块名称。

    所以我用了"import"mg-swift.h",它起作用了。

    Product Module Name in the build settings of target gives the correct module name which will work for your project


    在我的例子中,我必须将部署目标设置为至少"OS X 10.9",并且自动生成-Swift.h头。请记住,当您更改部署目标版本时,您可能会收到许多拒绝警告,特别是当您有一个较旧的、非常大的目标C代码库时。在我们的例子中,我们还需要在XIB文件和视图类中做很多工作。


    有时您只需要取消设置,然后在obj-c.m文件上再次设置目标成员身份。


    如果您使用的是类似于cocoapods的东西(在工作区之外工作,而不是在项目之外工作),那么在打开工作区和构建之前,请尝试打开项目并构建它。YMMV。


    我也遇到过类似的问题,但我的项目之前正在编译,在几个文件代码更改后突然出错。我花了一段时间才弄明白为什么我的项目swift.h文件出现"找不到文件"错误。我所做的代码更改有一些错误。Xcode没有指向Put这些错误,而是一直显示"找不到文件"错误。然后得到了以前版本代码的副本,并与新代码进行了比较,逐一合并了文件。每次文件合并后,都会编译项目以查找错误。所以底线是,如果代码中有错误,Xcode可能只显示myproject swift.h文件的"file not found error"。很可能您的项目中有编译错误。清除这些错误,它就会工作。


    这可能是一个明显的点(可能太明显了),但您必须在项目中至少有一个swift文件,才能生成头文件。如果您编写样板文件或配置代码的目的是稍后编写swift,则导入将无法工作。


    如果您以前能够构建一个项目,而没有与"ProductModuleName-Swift.h" not found错误相关的问题,而现在您又遇到了这些令人讨厌的错误,那么原因可能就在于您最近的更改。

    对我来说,这是(偶然)错误的.swift文件编码。恢复更改并手动返回,即可完成该任务。


    文件正在生成,但Xcode找不到(我用LouZell的答案来证明它正在生成)。

    这是我对混合objc/swift框架的修复(xcode 9.2):

  • 通过在finder(targetname swift.h)中搜索,在派生数据中查找预期生成的文件。
  • 在Xcode中将其拖到项目中,然后取消选中"复制文件"。
  • 单击xcode中的文件并打开文件检查器(右面板上的第一个选项卡)。
  • 将位置从相对组更改为相对生成产品
  • 前两个步骤应该允许您构建和使用您的项目,但后两个步骤允许它在其他计算机上工作(即,在团队项目上协作时,它仍然可以工作)。


    我必须从目标C项目中删除watchos2 swift代码。只有在Xcode提供生成-swift.h之后