首页 文章

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

提问于
浏览
234

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

在向项目添加Swift源文件后,我没有遇到“桥接 Headers ”的问题,即Objective-C到Swift .

但是--Swift.h头文件应该公开Swift类标记@objc或ObjC类的子类,是 nowhere 被发现:-(

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

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

30 回答

  • 10

    现在它有效 .

    • 项目必须具有 not 包含空格的产品模块名称 .

    • 定义模块必须在“打包”下的“构建设置”中设置为 Yes .

    最后工作 . 感谢大家的帮助:-)

  • 1

    我有类似的问题,发现你只能添加

    #import “ProductModuleName-Swift.h”

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

  • 1

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

    对我来说问题是它是一个鸡/蛋问题,因为我没有't see any build errors until I'实际上注释掉了 #import 声明:

    //#import "ProductModuleName-Swift.h"

    这揭示了我的Swift代码中的一堆其他错误 .

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

  • 1

    如果项目模块名称中包含空格,则必须使用下划线替换空格 .

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

    #import“My_Project-Swift.h”

  • 0

    如果你像我一样,你可能会错误地 Headers . 在猛击我的脑袋一段时间后,我在DerivedData中寻找文件,确定它就在那里 . 在我的设置上(我相信使用标准的派生数据文件夹):

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

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

    我正在使用Xcode版本6.2(6C86e)

  • 41

    *** The only important thing is: ***

    在目标中使用定义的“产品模块名称”,然后使用-Swift.h

    #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类必须从NSObject派生或者用@objc属性标记才能暴露给ObjectiveC / Foundation ||可可 ...

  • 54

    我想补充一个原因,你可能会发现这个问题 - 我正在创建一个混合了Swift和Objective-C代码的框架 . 我无法在框架外导入Swift类 - 我检查了-Swift.h文件,它正在生成但是为空 .

    事实证明这个问题非常非常简单 - 我没有宣布我的任何Swift课程公开!一旦我将public关键字添加到类中,我就可以在框架内外的类中使用它们 .

    另外值得注意的是,在框架内部(仅在另一个答案中提及.m文件)我必须将-Swift.h文件导入为:

    #import <FrameworkName/FrameworkName-Swift.h>
    
  • 0

    我有同样的问题 . 好像你必须调整设置(定义模块和产品模块名称) before 你添加了你的第一个Swift文件 .

    如果你之后这样做,即使你添加了更多Swift文件或删除Swift文件并创建一个新文件,也不会为该项目生成“* -Swift.h”文件 .

  • 7

    这是另一个未生成moduleName-Swift.h的变体 .

    我决定在我的项目中包含IOS Charts,但不想在同一目录中混合源,所以我将Charts Project文件夹放在我的代码's project folder. I dragged the Charts project into my Project'的Navigator Bar旁边,并将框架包含在我的项目目标的 Embedded Binaries 列表中 . 项目设置并在 Build Options 部分的项目 Build Settings 选项卡中将 Embedded Content Contains Swift Code 开关设置为yes .

    无论此处建议的其他开关或设置如何,我的项目的moduleName-Swift.h文件都不会生成 . 最后,使用Lou Z寻找-Swift.h文件的方法,我看到在我的项目的Charts.framework / Headers /中的xcode Build目录深处生成了一个Charts-Swift.h文件 .

    使用Daniel Gindi的ios-charts Swift包而不包含我项目源代码目录中的代码的解决方案是添加:

    #import "Charts/Charts-Swift.h"
    

    绘制我项目数据的模块 .

  • 4

    文件名始终以 Target 名称开头 . 它被称为产品名称,但实际上它是目标名称 . 因此,如果您希望它为新目标构建,请准备好期待 that_target-Swift.h 文件 .

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

    • 为每个目标添加一个预处理器,它是目标本身的名称(不含空格) . 防爆 . MY_TARGET=1 . 在每个目标的项目设置 - >构建设置 - >预处理器宏中添加此项 .

    • 如果您使用的是PCH文件,

    添加这些PCH文件中的行

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

    使用PCH文件的好处是您不必在任何地方都包含 Headers .

    • 如果您没有使用PCH文件,只需在单个 Headers 中添加这些相同的行,并在任何需要使用swift类的地方包含该 Headers .

    这应该工作得很好 .

  • 31

    请允许我分享我在旧的objc项目中使用Swift的经验 . 我没有必要将 Defines module 设置为 YES .

    在我的情况下,我需要手动确保有一个objc桥接 Headers . 我的构建设置中只显示生成的接口 Headers 名称 .

    Missing bridging header

    这导致生成MyApp-Swift.h文件,但没有任何我的Swift类的痕迹 .

    Apple文档说,在添加第一个swift文件时,系统会提示您创建桥接标头 . 好吧,我不是 . 我手动添加了一个 MyApp-Bridging-header.h 文件并在"Objective-C Bridging Header"字段中指向它 . 这使我的MyApp-Swift.h文件变成了我的Swift类 .

    文件:Importing Swift into Objective-C

  • 121

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

    看到我的回答:https://stackoverflow.com/a/27972946/337392

    编辑:这是因为公共与内部访问修饰符,我最终发现在Apple文档中解释: -

    默认情况下,生成的标头包含使用public修饰符标记的Swift声明的接口 . 如果您的应用目标具有Objective-C桥接标头,它还包含标有内部修饰符的那些 .

  • 1

    借调很多人在这里所拥有的,但添加了相关的屏幕截图 . Swift和Obj-C代码当然可以共存 . 这不是一场全部或全部比赛 .

    要访问Objective-C中的Swift文件,您需要做的就是将此调用添加到您的Obj-C文件中(在.m / implementation文件中):

    #import "{product_module_name}-Swift.h"
    

    (其中表示项目的产品模块名称) . 不要试图猜测您的产品模块名称或找出带有空格和特殊字符的边角情况,只需转到项目中的构建设置选项卡并输入“产品模块名称” - 检查员将向您展示 . 我的预期是我没想到的 . 如果您感到困惑,请查看此屏幕截图 .

    enter image description here

    要使Obj-c代码在Swift中工作,您只需添加一个桥接头文件并在那里导入相关的Obj-C头文件 .

  • 5

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

    1.Remove all the swift files you have added, and compile the code, without any errors.

    ----------

    enter image description here

    ----------

    2.Go to the "Projects" build settings, and set the product module name. Project must have a Product Module Name that does not include spaces.

    ----------

    enter image description here

    ----------

    3.Defines Module must be set to Yes in Build Settings, under Packaging, in your project, and not target!

    ----------

    enter image description here

    ----------

    4.Now create a swift file or a view controller, in file-> newFile->

    ----------

    enter image description here

    ----------

    它会要求创建一个桥接头,允许它制作一个 . 如果您拒绝了一次,则必须手动添加-Bridging-Header.h

    5.Add @objc in the controller, to tell the compiler that there is some swift file, which needs to be exposed to ObjectiveC

    ----------

    enter image description here

    ----------

    6.Build the project and import #import "-Swift.h" in any of the objectiveC controller, and it will work! You can Command-click on it to see the actual file!

    ----------

    enter image description here

    ----------

    希望这可以帮助!

  • 3

    最重要的是 This file is invisible!!! 至少它在Xcode6 beta5中 . 您的工作区中不会有名为"YourModule-Swift.h"的文件 . 只需确保您具有模块名称并将模块设置为yes,并在Objective-C类中使用它 .

  • 13

    这个答案解决了你可能已经有一些调用Swift类的Objective-C代码然后你开始收到这个错误的用例 .

    How To Fix Issue

    以下步骤最终为我解决了所有问题 . 我在上面读过一个提到“鸡肉和鸡蛋”的人,正是这个概念让我开始了这个过程 . 这个显式进程表明,必须删除任何引用Swift类的Objective-C代码,直到生成头文件为止 .

    • 注释掉Objective-C实现文件中的#import "ProductModuleName-Swift.h"语句

    • 将Objective-C实现文件中的任何引用注释掉Swift类

    • 清洁和建造

    • 解决所有错误/警告

    • 删除#import "ProductModuleName-Swift.h"语句的注释

    • 清理和构建(成功或修复任何剩余的错误, verify that you are not referencing any Swift classes in Objective-C at this point . 如果是这样暂时将这些错误评论出来)

    • 验证 Cmd-Clicking 是否由#import "ProductModuleName-Swift.h"语句的类名生成 Cmd-Clicking

    • 删除Objective-C实现文件中引用Swift类的代码的注释 .

    • 正常清理和构建(应生成"ProductModuleName-Swift.h",并且可以正常使用引用Swift类的Objective-C代码)

    Nota Bene: 关于将空格更改为下划线并将上述模块定义为YES的答案仍然适用于执行此过程,Apple Documentation中指定的规则也是如此 .

    Bridging Header Path

    在一个错误中,在构建过程中未找到文件ProductModuleName-Bridging-Header.h . 这个事实上产生了错误

    <unknown>:0:错误:桥接 Headers '/Users/Shared/Working/abc/abc-Bridging-Header.h'不存在

    仔细检查错误表明该文件永远不会存在于所描述的位置,因为它实际上位于( a wrong path

    '/Users/Shared/Working/abc/abc/abc-Bridging-Header.h' . 快速搜索目标/项目构建设置以手动进行更正,并再次自动生成abc-Swift.h文件 .

    build-settings

  • 41

    您必须在Objective-C类中导入标头,即:

    #import “ProductModuleName-Swift.h”
    

    它是自动生成的,在引用中它表示“目标中的任何Swift文件都将在包含此import语句的Objective-C .m文件中可见” .

  • 0

    An actual file in the project is not created ([ProductModuleName] -Swift.h) . Cmd点击导入或者动态生成它(并在内存中),这样你就可以看到链接是如何完成的,或者在某个Xcode缓存目录中的某个地方打开一个文件,但它不在项目目录中 .

    您需要将 Defines Module project prop(在目标的构建设置中)设置为 Yes ,如果您的模块名称包含空格或短划线 - 请在[ProductModuleName] -Swift.h文件的所有导入中使用_ .

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

    因此,如果我的模块(项目)被命名为“测试项目”,我会在我的项目的.pch文件中导入它(就在那里):

    #import "Test_Project-Swift.h"
    
  • 2

    对于使用“ . ”的人来说,只是一个人 . 在那里项目名称 . Xcode将取代“ . ”带有下划线“_”的Swift版本的桥接头文件 . 奇怪的是,生成的Bridging-Header.h不会替换带下划线的句点 .

    例如,名为My.Project的项目将具有以下桥接头文件名 .

    Bridging-Header.h (Autogenerated)

    My.Project桥接,Header.h

    Swift.h

    My_Project.h

    我希望这可以帮助任何使用过一段时间并且像我一样陷入困境的人 . 可以在以下位置找到此文件 .

    Macintosh HD / Users / user / Library / Developer / Xcode / DerivedData / My.Project-fntdulwpbhbbzdbyrkhanemcrfil / Build / Intermediates / My.Project.build / Debug-iphonesimulator / My.Project.build / DerivedSources

    照顾自己,

    乔恩

  • 12

    项目必须具有不包含空格的模块名称 . 在“打包”下的“构建设置”中,必须将“模块”设置为“是” . 注释掉#import语句:

    如果您仍然在导入“ProductModuleName-Swift.h”时遇到错误

    // #import“ProductModuleName-Swift.h”

    这揭示了我的Swift代码中的一堆其他错误 .

    一旦我修复了这些新错误并成功构建了源代码,我就会对#import和宾果游戏进行注释! Headers 已创建并正确导入:)

  • 0

    我找到了一个总能对我有用的技巧 .

    • 在appDelegate.h文件和ProductName-Prefix.pch文件中创建#import "ProductModuleName-Swift.h" . 如果你没有在xcode 6中使用它,你可以用这种方式创建Why isn't ProjectName-Prefix.pch created automatically in Xcode 6?

    • 如果从appDelegate.h文件中收到有关"ProductModuleName-Swift.h"删除它的错误,命令转移k来清理代码 .

    • 再次清理代码 . 现在一切都会像魅力一样发挥作用

    • 如果再次收到有关"ProductModuleName-Swift.h"的错误,现在再次在appDelegate.h文件中创建并再次清理代码 .

    这样做(每次收到此错误时,从appDelegate.h文件中删除并创建“ProductModuleName-Swift.h”并清理代码)以使其静音 .

  • 4

    我找到了这个解决方案

    • 创建SwiftBridge.h

    • 把#import“ProductModuleName-Swift.h”

    • 将此.h文件设为公共(重要)选择文件 - >在显示文件检查器(右栏) - >公开

    现在你可以

    #import "SwiftBridge.h"
    

    而不是ProductModuleName-Swift.h

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

  • 2

    我很难确定我的模块名称/ objective-c导入的swift标头 . 我也在这里读了很多文章 .

    但是对于项目名称及其所有包含的特殊字符(无论是'.'还是数字或空格)的确定答案 - 您可以在目标的构建设置下的“ Product Module Name ”中找到适合您的文本 .

    例如,我的目标名称以数字开头 - “1mg”,上面提到的字段显示“_mg”作为我的模块名称 .

    所以我使用#import“_mg-Swift.h”并且它有效 .

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

  • 24

    在我的情况下,我必须将部署目标设置为至少“OS X 10.9”并自动生成 -Swift.h 标头 . 请记住,更改部署目标版本时可能会收到大量弃用警告,尤其是当您拥有较旧且非常大的Objective C代码库时 . 在我们的例子中,我们在XIB文件和视图类中还有很多工作要做 .

  • 0

    如果您之前能够构建项目,没有与 “ProductModuleName-Swift.h” not found 错误相关的问题,现在您再次收到那些令人讨厌的错误,原因可能在于您最近的更改 .

    对我来说这是(偶然的)不正确的 .swift 文件编码 . 恢复更改并手动返回,完成工作 .

  • 12

    这可能是一个显而易见的点(可能太明显),但您必须在项目中至少有一个swift文件才能生成 Headers . 如果您正在编写样板代码或配置代码,以便稍后编写swift,则导入将无效 .

  • 0

    我不得不从Objective C项目中删除WatchOS2 swift代码 . 只有在XCode提供生成-Swift.h之后

  • 156

    我有类似的问题,但我的项目之前编译,并在几个文件代码更改后突然出现错误 . 我花了一些时间弄清楚为什么我的myproject-swift.h文件出现'找不到文件'错误 . 我所做的代码更改有一些错误 . Xcode没有指出那些错误而是一直显示'文件未找到错误' . 然后得到了以前版本代码的副本,我与新代码进行了比较并逐一合并了文件 . 每个文件合并后,编译项目以查找错误 . 所以底线是你的代码中有错误Xcode可能只显示myproject-swift.h文件的'找不到文件错误' . 很可能你的项目中有编译错误 . 清理那些错误,它会起作用 .

  • 11

    如果您正在使用Cocoapods之类的东西(并且在工作区外工作而不是项目),请在打开工作区和构建之前尝试打开项目并构建它 . 因人而异 .

  • 2

    有时您只需要取消设置,然后再次在obj-c .m文件中设置目标成员资格 .

相关问题