Can't use Swift classes inside Objective-C
我尝试在我的应用程序中集成
编辑:苹果公司说:"当你将Swift代码导入到Objective-C时,你依靠一个
现在,当我想导入该文件时,它会给出一个错误:
1 2 3 4 5 | //MainMenu.m #import"myProjectModule-Swift.h" //Error: 'myProjectModule-Swift.h' file not found @implementation MainMenu |
这是我的fbmanager.swift文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | @objc class FBManager: NSObject { var descr ="FBManager class" init() { super.init() } func desc(){ println(descr) } func getSharedGameState() -> GameState{ return GameState.sharedGameState() //OK! GameState is written in Objective-C and no error here } } |
我花了大约4个小时在我的基于
执行您的swift类:
1 2 3 4 5 6 | import Foundation // use @objc or @objcMembers annotation if necessary class Foo { //.. } |
打开生成设置并检查这些参数:
- 定义模块:
YES 。
Copy & Paste parameter name in a search bar
- 产品模块名称:
myproject 。
Make sure that your Product Module Name doesn't contain any special characters
- 安装Objective-C兼容头:
YES 。
Once you've added
*.swift file to the project this property will appear in Build Settings - Objective-C生成的接口头:
myproject-Swift.h 。
This header is auto generated by Xcode
- Objective-C桥接头:
$(SRCROOT)/myproject-Bridging-Header.h 。
在您的*.m文件中导入swift接口头文件
1 | #import"myproject-Swift.h" |
Don't pay attention to errors and warnings.
不要自己创建头文件。删除您创建的。
确保您的swift类被标记为
如果您的项目中有任何编译器错误,Xcode将不会生成该文件-请确保您的项目构建干净。
允许xcode进行工作,不要手动添加/创建swift头。把@objc加到你的swift类前。
1 | @objc class YourSwiftClassName: UIViewController |
在项目设置中,搜索以下标志并将其更改为"是"(项目和目标)
1 2 3 | Defines Module : YES Always Embed Swift Standard Libraries : YES Install Objective-C Compatibility Header : YES |
然后清理项目并构建一次,在构建成功(可能应该)之后,在objective-c class.m文件的头文件下面导入
1 | #import"YourProjectName-Swift.h" |
嘘声!
也可能对那些有框架目标的人有帮助:
自动生成的头文件的import语句与app目标看起来有点不同。除其他答案中提到的其他内容外,使用
1 | #import <ProductName/ProductModuleName-Swift.h> |
而不是
1 | #import"ProductModuleName-Swift.h" |
根据苹果公司关于框架目标混合和匹配的文档。
确保您的项目定义了一个模块,并且为该模块提供了一个名称。然后重建,xcode将创建
可以在项目设置中设置模块定义和模块名称。
详情:Xcode 8.1中带有Swift 3代码的Objective-C项目
任务:
全样本1。使用swift枚举的objective-c类
ObjcClass.h
1 2 3 4 5 6 7 8 9 10 11 12 13 | #import <Foundation/Foundation.h> typedef NS_ENUM(NSInteger, ObjcEnum) { ObjcEnumValue1, ObjcEnumValue2, ObjcEnumValue3 }; @interface ObjcClass : NSObject + (void) PrintEnumValues; @end |
ObjcClass.m
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | #import"ObjcClass.h" #import"SwiftCode.h" @implementation ObjcClass + (void) PrintEnumValues { [self PrintEnumValue:SwiftEnumValue1]; [self PrintEnumValue:SwiftEnumValue2]; [self PrintEnumValue:SwiftEnumValue3]; } + (void) PrintEnumValue:(SwiftEnum) value { switch (value) { case SwiftEnumValue1: NSLog(@"-- SwiftEnum: SwiftEnumValue1"); break; case SwiftEnumValue2: case SwiftEnumValue3: NSLog(@"-- SwiftEnum: long value = %ld", (long)value); break; } } @end |
检测目标C代码中的Swift代码
在我的示例中,我使用swiftcode.h在objective-c中检测swift代码。此文件自动生成(我没有在项目中创建此头文件的物理副本),您只能设置此文件的名称:
If the compiler can not find your header file Swift code, try to compile the project.
2。使用Objective-C枚举的Swift类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | import Foundation @objc enum SwiftEnum: Int { case Value1, Value2, Value3 } @objc class SwiftClass: NSObject { class func PrintEnumValues() { PrintEnumValue(.Value1) PrintEnumValue(.Value2) PrintEnumValue(.Value3) } class func PrintEnumValue(value: ObjcEnum) { switch value { case .Value1, .Value2: NSLog("-- ObjcEnum: int value = \(value.rawValue)") case .Value3: NSLog("-- ObjcEnum: Value3") break } } } |
检测swift代码中的objective-c代码
您需要创建桥接头文件。当您在objective-c项目中添加swift文件,或在swift项目xcode中添加objective-c文件时,将建议您创建桥接头文件。
您可以在此处更改桥接头文件名:
Bridging-Header.h
1 | #import"ObjcClass.h" |
用法
1 2 3 4 5 | #import"SwiftCode.h" ... [ObjcClass PrintEnumValues]; [SwiftClass PrintEnumValues]; [SwiftClass PrintEnumValue:ObjcEnumValue3]; |
结果
更多样品Full integration steps Objective-c and Swift described above. Now I will write some other code examples.
三。从目标C代码调用swift类
Swift class
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | import Foundation @objc class SwiftClass:NSObject { private var _stringValue: String var stringValue: String { get { print("SwiftClass get stringValue") return _stringValue } set { print("SwiftClass set stringValue = \(newValue)") _stringValue = newValue } } init (stringValue: String) { print("SwiftClass init(String)") _stringValue = stringValue } func printValue() { print("SwiftClass printValue()") print("stringValue = \(_stringValue)") } } |
Objective-C code (calling code)
1 2 3 4 | SwiftClass *obj = [[SwiftClass alloc] initWithStringValue: @"Hello World!"]; [obj printValue]; NSString * str = obj.stringValue; obj.stringValue = @"HeLLo wOrLd!!!"; |
结果
4。从swift代码调用objective-c类Objective-C class (ObjcClass.h)
1 2 3 4 5 6 7 | #import <Foundation/Foundation.h> @interface ObjcClass : NSObject @property NSString* stringValue; - (instancetype) initWithStringValue:(NSString*)stringValue; - (void) printValue; @end |
ObjcClass.m
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | #import"ObjcClass.h" @interface ObjcClass() @property NSString* strValue; @end @implementation ObjcClass - (instancetype) initWithStringValue:(NSString*)stringValue { NSLog(@"ObjcClass initWithStringValue"); _strValue = stringValue; return self; } - (void) printValue { NSLog(@"ObjcClass printValue"); NSLog(@"stringValue = %@", _strValue); } - (NSString*) stringValue { NSLog(@"ObjcClass get stringValue"); return _strValue; } - (void) setStringValue:(NSString*)newValue { NSLog(@"ObjcClass set stringValue = %@", newValue); _strValue = newValue; } @end |
Swift code (calling code)
1 2 3 4 5 | if let obj = ObjcClass(stringValue: "Hello World!") { obj.printValue() let str = obj.stringValue; obj.stringValue ="HeLLo wOrLd!!!"; } |
结果
5。在目标C代码中使用swift扩展Swift extension
1 2 3 4 5 | extension UIView { static func swiftExtensionFunc() { NSLog("UIView swiftExtensionFunc") } } |
Objective-C code (calling code)
1 | [UIView swiftExtensionFunc]; |
6。在swift代码中使用objective-c扩展
Objective-C extension (UIViewExtension.h)
1 2 3 4 5 | #import <UIKit/UIKit.h> @interface UIView (ObjcAdditions) + (void)objcExtensionFunc; @end |
UIViewExtension.m
1 2 3 4 5 | @implementation UIView (ObjcAdditions) + (void)objcExtensionFunc { NSLog(@"UIView objcExtensionFunc"); } @end |
Swift code (calling code)
1 | UIView.objcExtensionFunc() |
我也有同样的问题,结果发现模块名称中的特殊符号被xcode替换(在我的例子中,破折号最后是下划线)。在"项目设置"中,选中"模块名称"以查找项目的模块名称。之后,使用
文件是自动创建的(这里是Xcode6.3.2)。但您不会看到它,因为它在派生数据文件夹中。用
我有个问题,xcode把我的
只包括#在.m或.h文件中导入"myproject swift.h"
另外,你在档案检查员中找不到"myproject swift.h",它是隐藏的。但它是由应用程序自动生成的。
有两个条件,
- 使用目标C文件中的swift文件。
- 使用Swift文件中的目标C文件。
因此,为此,您必须遵循以下步骤:
- 将您的swift文件添加到Objective-C项目中,反之亦然。
- 创建头文件(.h)。
转到"生成设置",并通过搜索执行以下步骤,
- 搜索文本"brid"并设置头文件的路径。
- "定义模块":是。
- "始终嵌入Swift标准库":是。
- "Install objective-c compatibility header":是。
之后,清理并重建您的项目。
使用目标C文件中的swift文件。在这种情况下,首先在swift文件中的类之前写"@objc"。
在那之后,在你的目标C文件中,写下这个,
1 | #import"YourProjectName-Swift.h" |
使用Swift文件中的目标C文件。
在这种情况下,在你的头文件中,写下这个,
1 | #import"YourObjective-c_FileName.h" |
我希望这对你有帮助。
@SIG答案是最好的答案之一,但是它对我来说不适用于旧项目(不是新项目!),我需要一些修改。经过许多变化,我找到了我的食谱(使用xcode 7.2):
最后一点(5)至关重要。我只把它放在第二部分(目标字段),项目字段应该留空:,否则,它不会为我生成正确的"project swift.h"文件(不包括swift方法)。
在我的例子中,除了这些步骤:
我需要将该类作为公共类来创建ProductName Swift.h文件:
1 2 3 4 5 6 7 | import UIKit @objc public class TestSwift: NSObject { func sayHello() { print("Hi there!") } } |
我也遇到了同样的问题,最后看来他们并不是同一个目标。objc类附加到target1和target2,swift类只附加到target1,在objc类中不可见。
希望这能帮助别人。
我刚刚发现向项目添加一个swift文件目录是行不通的。您需要先为目录创建一个组,然后添加swift文件…
好吧,在阅读了所有的评论,并尝试阅读和再次尝试之后,我设法在我的大型obj-c项目中加入了swift类。所以,谢谢你的帮助。我想分享一个帮助我更好地理解这个过程的提示。在.m类中,转到swift目标名称的导入行import"mytargetname swift.h"然后点击键:
命令+鼠标单击->跳转到定义
在这里,您可以看到从swift到obj-c的所有翻译,然后您将发现obj-c中重新声明的各种函数。希望这条建议对你的帮助和对我的帮助一样多。
我也有同样的错误:找不到
我不需要更改构建中的任何设置,也不需要将@obj添加到类中。
我所要做的就是创建桥头,当我在Objective-C项目中创建Swift类时自动创建桥头。然后我就不得不这么做
导入"bedtime swift.h"<-在需要使用该swift文件的objective-c文件中。我有一个问题,我将向我的objective-c桥接头添加类,在那些导入的objective-c头中,它们试图导入swift头。它不喜欢那样。
因此,在所有使用swift但也是桥接的objective-c类中,关键是确保在头文件中使用forward类声明,然后在.m文件中导入"*-swift.h"文件。
我的问题是,Xcode创建了网桥文件后,我卡住了,但头文件名myprojectname swift.h中仍然有错误。
1.我登记终端并搜索所有自动创建的Swift Bridge文件:
您可以看到Xcode创建了什么。
我的问题是-swift.h文件的自动生成无法理解CustomDebugStringConvertible的子类。我将类改为nsObject的子类。之后,-swift.h文件正确地包含了类。
在做了以上所有的事情之后,我仍然有错误。我的问题是我需要的swift文件由于某种原因没有添加到包资源中。
我通过转到[我的目标]>构建阶段>复制捆绑资源修复了这个问题,然后单击加号按钮并添加了Swift文件。