ios 不能在 Objective-C 中使用 Swift 类
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24206732/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Can't use Swift classes inside Objective-C
提问by dnnagy
I try to integrate Swift
code in my app.My app is written in Objective-C
and I added a Swift
class. I've done everything described here. But my problem is that Xcode
haven't created the -Swift.h
file, only the bridging headers. So I created it, but it's actually empty.
I can use all my ObjC classes in Swift, but I can't do it vice versa. I marked my swift class with @objc
but it didn't help. What can I do now?
我尝试Swift
在我的应用程序中集成代码。我的应用程序已编写Objective-C
并添加了一个Swift
类。我已经完成了这里描述的所有事情。但我的问题是Xcode
还没有创建-Swift.h
文件,只有桥接头。所以我创建了它,但它实际上是空的。我可以在 Swift 中使用我所有的 ObjC 类,但反之则不行。我用 标记了我的 swift 类,@objc
但它没有帮助。我现在能做什么?
EDIT: Apple says:" When you import Swift code into Objective-C, you rely on an Xcode-generated
header file to expose those files to Objective-C. [...] The name of this header is your product module name followed by adding “-Swift.h”. "
编辑:Apple 说:“当你将 Swift 代码导入到 Objective-C 中时,你依赖于一个Xcode-generated
头文件来将这些文件暴露给 Objective-C。[...] 这个头文件的名称是你的产品模块名称,然后添加“ -Swift.h”。”
Now when I want to import that File, it gives an error:
现在当我想导入该文件时,它给出了一个错误:
//MainMenu.m
#import "myProjectModule-Swift.h" //Error: 'myProjectModule-Swift.h' file not found
@implementation MainMenu
Here is my FBManager.swift file:
这是我的 FBManager.swift 文件:
@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
}
}
回答by sig
I spent about 4 hours trying to enable Swift
in my Xcode
Objective-C based project. My myproject-Swift.h
file was created successfully, but my Xcode
didn't see my Swift-classes
. So, I decided to create a new Xcode
Objc-based project and finally, I found the right answer! Hope this post will help someone :-)
我花了大约4个小时努力,使Swift
我在Xcode
基于Objective-C的项目。我的myproject-Swift.h
文件已成功创建,但我Xcode
没有看到我的Swift-classes
. 所以,我决定创建一个新Xcode
的基于 Objc 的项目,最后,我找到了正确的答案!希望这篇文章能帮助别人:-)
Step by step Swift integration for Xcode Objc-based project:
基于 Xcode Objc 的项目的逐步 Swift 集成:
- Create new
*.swift
file (in Xcode) or add it by using Finder. - Create an
Objective-C bridging header
when Xcode asks you about that. Implement your Swift class:
import Foundation // use @objc or @objcMembers annotation if necessary class Foo { //.. }
Open Build Settings and check these parameters:
- Defines Module :
YES
Copy & Paste parameter name in a search bar
- Product Module Name :
myproject
Make sure that your Product Module Name doesn't contain any special characters
- Install Objective-C Compatibility Header :
YES
Once you've added
*.swift
file to the project this property will appear in Build Settings - Objective-C Generated Interface Header :
myproject-Swift.h
This header is auto-generated by Xcode
- Objective-C Bridging Header :
$(SRCROOT)/myproject-Bridging-Header.h
- Defines Module :
Import Swift interface header in your *.m file.
#import "myproject-Swift.h"
Don't pay attention to errors and warnings.
- Clean and rebuild your Xcode project.
- Profit!
- 创建新
*.swift
文件(在 Xcode 中)或使用 Finder 添加它。 Objective-C bridging header
当 Xcode 询问您时创建一个。实现你的 Swift 类:
import Foundation // use @objc or @objcMembers annotation if necessary class Foo { //.. }
打开构建设置并检查这些参数:
- 定义模块:
YES
在搜索栏中复制和粘贴参数名称
- 产品模块名称:
myproject
确保您的产品模块名称不包含任何特殊字符
- 安装 Objective-C 兼容性头文件:
YES
将
*.swift
文件添加到项目后,此属性将出现在构建设置中 - Objective-C 生成的接口头文件:
myproject-Swift.h
此标头由 Xcode 自动生成
- Objective-C 桥接头文件:
$(SRCROOT)/myproject-Bridging-Header.h
- 定义模块:
在 *.m 文件中导入 Swift 接口头文件。
#import "myproject-Swift.h"
不要注意错误和警告。
- 清理并重建您的 Xcode 项目。
- 利润!
回答by Bill
Don't create the header file yourself. Delete the one you created.
不要自己创建头文件。删除您创建的那个。
Make sure your Swift classes are tagged with @objc
or inherit from a class that derives (directly or indirectly) from NSObject
.
确保您的 Swift 类被标记为@objc
或继承自(直接或间接)派生自NSObject
.
Xcode won't generate the file if you have any compiler errors in your project - make sure your project builds cleanly.
如果您的项目中有任何编译器错误,Xcode 将不会生成该文件 - 确保您的项目构建干净。
回答by Bharat Modi
Allow Xcode to do its work, do not add/create Swift header manually. Just add @objc before your Swift class ex.
允许 Xcode 完成它的工作,不要手动添加/创建 Swift 头文件。只需在 Swift 类前添加 @objc 即可。
@objc class YourSwiftClassName: UIViewController
In your project setting search for below flags and change it to YES (Both Project and Target)
在您的项目设置中搜索以下标志并将其更改为是(项目和目标)
Defines Module : YES
Always Embed Swift Standard Libraries : YES
Install Objective-C Compatibility Header : YES
Then clean the project and build once, after build succeed (it should probably) import below header file in your objective-c class .m file
然后清理项目并构建一次,构建成功后(应该可能)在您的objective-c 类.m 文件中导入下面的头文件
#import "YourProjectName-Swift.h"
Boooom!
呸!
回答by Jeehut
Also probably helpful for those of you with a Framework target:
也可能对那些有框架目标的人有帮助:
The import statementof the auto-generated header file looks a bit differentfrom app targets. In addition to the other things mentioned in other answers use
自动生成的头文件的import 语句看起来与应用程序目标有点不同。除了其他答案中提到的其他事情之外,请使用
#import <ProductName/ProductModuleName-Swift.h>
instead of
代替
#import "ProductModuleName-Swift.h"
as per Apples documentation on Mix & Matchfor framework targets.
根据 Apples 关于框架目标的Mix & Match 的文档。
回答by Vasily Bodnarchuk
Details:Objective-C project with Swift 3 code in Xcode 8.1
详细信息:在 Xcode 8.1 中使用 Swift 3 代码的 Objective-C 项目
Tasks:
任务:
- Use swift enum in objective-c class
- Use objective-c enum in swift class
- 在objective-c类中使用swift枚举
- 在swift类中使用objective-c枚举
FULL SAMPLE
完整样本
1. Objective-C class which use Swift enum
1. 使用 Swift 枚举的 Objective-C 类
ObjcClass.h
对象类文件
#import <Foundation/Foundation.h>
typedef NS_ENUM(NSInteger, ObjcEnum) {
ObjcEnumValue1,
ObjcEnumValue2,
ObjcEnumValue3
};
@interface ObjcClass : NSObject
+ (void) PrintEnumValues;
@end
ObjcClass.m
对象类
#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
Detect Swift code in Objective-C code
在 Objective-C 代码中检测 Swift 代码
In my sample I use SwiftCode.h to detect Swift code in Objective-C. This file generate automatically (I did not create a physical copy of this header file in a project), and you can only set name of this file:
在我的示例中,我使用 SwiftCode.h 来检测 Objective-C 中的 Swift 代码。这个文件是自动生成的(我没有在项目中创建这个头文件的物理副本),你只能设置这个文件的名称:
If the compiler can not find your header file Swift code, try to compile the project.
如果编译器找不到您的头文件 Swift 代码,请尝试编译该项目。
2. Swift class which use Objective-C enum
2.使用Objective-C枚举的Swift类
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
}
}
}
Detect Objective-C code in Swift code
在 Swift 代码中检测 Objective-C 代码
You need to create bridging header file. When you add Swift file in Objective-C project, or Objective-C file in swift project Xcode will suggest you to create bridging header.
您需要创建桥接头文件。当你在 Objective-C 项目中添加 Swift 文件,或者在 Swift 项目中添加 Objective-C 文件时,Xcode 会建议你创建桥接头。
You can change bridging header file name here:
您可以在此处更改桥接头文件名:
Bridging-Header.h
Bridging-Header.h
#import "ObjcClass.h"
Usage
用法
#import "SwiftCode.h"
...
[ObjcClass PrintEnumValues];
[SwiftClass PrintEnumValues];
[SwiftClass PrintEnumValue:ObjcEnumValue3];
Result
结果
MORE SAMPLES
更多样品
Full integration steps Objective-c and Swift described above. Now I will write some other code examples.
上面描述的完整集成步骤 Objective-c 和 Swift。现在我将编写一些其他代码示例。
3. Call Swift class from Objective-c code
3.从Objective-c代码调用Swift类
Swift class
斯威夫特类
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)
Objective-C 代码(调用代码)
SwiftClass *obj = [[SwiftClass alloc] initWithStringValue: @"Hello World!"];
[obj printValue];
NSString * str = obj.stringValue;
obj.stringValue = @"HeLLo wOrLd!!!";
Result
结果
4. Call Objective-c class from Swift code
4. 从 Swift 代码中调用 Objective-c 类
Objective-C class (ObjcClass.h)
Objective-C 类 (ObjcClass.h)
#import <Foundation/Foundation.h>
@interface ObjcClass : NSObject
@property NSString* stringValue;
- (instancetype) initWithStringValue:(NSString*)stringValue;
- (void) printValue;
@end
ObjcClass.m
对象类
#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)
Swift 代码(调用代码)
if let obj = ObjcClass(stringValue: "Hello World!") {
obj.printValue()
let str = obj.stringValue;
obj.stringValue = "HeLLo wOrLd!!!";
}
Result
结果
5. Use Swift extension in Objective-c code
5. 在 Objective-c 代码中使用 Swift 扩展
Swift extension
斯威夫特扩展
extension UIView {
static func swiftExtensionFunc() {
NSLog("UIView swiftExtensionFunc")
}
}
Objective-C code (calling code)
Objective-C 代码(调用代码)
[UIView swiftExtensionFunc];
6. Use Objective-c extension in swift code
6.在swift代码中使用Objective-c扩展
Objective-C extension (UIViewExtension.h)
Objective-C 扩展 (UIViewExtension.h)
#import <UIKit/UIKit.h>
@interface UIView (ObjcAdditions)
+ (void)objcExtensionFunc;
@end
UIViewExtension.m
UIViewExtension.m
@implementation UIView (ObjcAdditions)
+ (void)objcExtensionFunc {
NSLog(@"UIView objcExtensionFunc");
}
@end
Swift code (calling code)
Swift 代码(调用代码)
UIView.objcExtensionFunc()
回答by Leo Natan
Make sure your project defines a module and you have given a name to the module. Then rebuild, and Xcode will create the -Swift.h
header file and you will be able to import.
确保您的项目定义了一个模块并且您已经为该模块命名。然后重建,Xcode 会创建-Swift.h
头文件,你就可以导入了。
You can set module definition and module name in your project settings.
您可以在项目设置中设置模块定义和模块名称。
回答by Max Mikheyenko
I had the same issue and it turned out special symbols in the module name are replaced by xcode (in my case dashes ended up being underscores). In project settings check "module name" to find the module name for your project. After that either use ModuleName-Swift.h
or rename the module in settings.
我遇到了同样的问题,结果模块名称中的特殊符号被 xcode 替换(在我的情况下,破折号最终变成了下划线)。在项目设置中,选中“模块名称”以查找项目的模块名称。之后,ModuleName-Swift.h
在设置中使用或重命名模块。
回答by brainray
The file is created automatically (talking about Xcode 6.3.2 here). But you won't see it, since it's in your Derived Data folder. After marking your swift class with @objc
, compile, then search for Swift.h
in your Derived Data folder. You should find the Swift header there.
该文件是自动创建的(这里讨论的是 Xcode 6.3.2)。但是您不会看到它,因为它在您的派生数据文件夹中。用 标记 swift 类后@objc
,编译,然后Swift.h
在派生数据文件夹中搜索。您应该在那里找到 Swift 标头。
I had the problem, that Xcode renamed my my-Project-Swift.h
to my_Project-Swift.h
Xcode doesn't like
"." "-"
etc. symbols. With the method above you can find the filename and import it to a Objective-C class.
我遇到了问题,Xcode 将 my 重命名my-Project-Swift.h
为my_Project-Swift.h
Xcode 不喜欢
"." "-"
等符号。使用上面的方法,您可以找到文件名并将其导入到 Objective-C 类中。
回答by Svitlana
Just include #import "myProject-Swift.h" in .m or .h file
只需在 .m 或 .h 文件中包含 #import "myProject-Swift.h"
P.S You will not find "myProject-Swift.h" in file inspector it's hidden. But it is generated by app automatically.
PS 你不会在文件检查器中找到“myProject-Swift.h”,它是隐藏的。但它是由应用程序自动生成的。
回答by vikas prajapati
There is two condition,
有两个条件,
- Use your swift file in objective c file.
- Use your objective c file in swift file.
- 在目标 c 文件中使用您的 swift 文件。
- 在 swift 文件中使用您的目标 c 文件。
So, For that purpose, you have to follow this steps:
因此,为此,您必须遵循以下步骤:
- Add your swift file in an objective-c project or vice-versa.
- Create header(.h) file.
Go to Build Settingsand perform below steps with search,
- search for this text "brid" and set a path of your header file.
- "Defines Module": YES.
- "Always Embed Swift Standard Libraries" : YES.
- "Install Objective-C Compatibility Header" : YES.
- 在 Objective-c 项目中添加你的 swift 文件,反之亦然。
- 创建头(.h)文件。
转到构建设置并通过搜索执行以下步骤,
- 搜索此文本“brid”并设置头文件的路径。
- “定义模块”:是的。
- “始终嵌入 Swift 标准库”:是的。
- “安装 Objective-C 兼容性头文件”:是。
After that, clean and rebuild your project.
之后,清理并重建您的项目。
Use your swift file in objective c file.
在目标 c 文件中使用您的 swift 文件。
In that case,First write "@objc" before your class in swift file.
在这种情况下,首先在 swift 文件中的类之前写入“@objc”。
After that ,In your objective c file, write this,
之后,在你的目标c文件中,写下这个,
#import "YourProjectName-Swift.h"
Use your objective c file in swift file.
在 swift 文件中使用您的目标 c 文件。
In that case, In your header file, write this,
在这种情况下,在你的头文件中,写下这个,
#import "YourObjective-c_FileName.h"
I hope this will help you.
我希望这能帮到您。