从 Objective-C 类调用 Swift 函数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24078043/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 21:17:27  来源:igfitidea点击:

Call Swift function from Objective-C class

objective-cswift

提问by Eloreden

I have an old Objective-C project and I want to call new Swift function and object, I have create the file "<ProjectName>-Bridging-Header.h" and "<ProjectName>-Swift.h"

我有一个旧的 Objective-C 项目,我想调用新的 Swift 函数和对象,我已经创建了文件“ <ProjectName>-Bridging-Header.h”和“ <ProjectName>-Swift.h

was easy for me call the function from Swift to Objective-C but I have a problem for reverse.

对我来说,从 Swift 调用函数到 Objective-C 很容易,但我有一个反向问题。

So I have create a simple class "System.Swift"

所以我创建了一个简单的类“System.Swift”

import Foundation

@objc class System : NSObject {

@objc func printSome() {
    println("Print line System");
    }
}

now I have try to follow the documentation hereand inside the <...>-Swift.hfile I have write this

现在我尝试按照文档here<...>-Swift.h我写的文件里面

@class System;

@interface System : NSObject

-(void)printSome;

@end

and I have import it inside my Objective-C Class. At this point inside my Objective C class (currently UIViewController) of my Objective-C code I have try to call "printSome" method:

我已经将它导入到我的 Objective-C 类中。此时,在我的 Objective-C 代码的 Objective C 类(当前为 UIViewController)中,我尝试调用“printSome”方法:

- (void)viewDidLoad
{
    [super viewDidLoad];
    System * sis = [[System alloc] init];
    [sis printSome];
    //any additional setup after loading the view from its nib.
}

now I have the following Error:

现在我有以下错误:

Undefined symbols for architecture i386: "_OBJC_CLASS_$_System", referenced from: objc-class-ref in "ObjectiveC_Class_That_Call_Swift_Object".o ld: symbol(s) not found for architecture i386 clang: error: linker command failed with exit code 1 (use -v to see invocation)

体系结构 i386 的未定义符号:“_OBJC_CLASS_$_System”,引用自:“ObjectiveC_Class_That_Call_Swift_Object”中的 objc-class-ref。 -v 查看调用)

采纳答案by Eloreden

Problem Solved, I previously create and included a new .hfile in my Objective-Cclass named <ProductModuleName>-Swift.hbut, as i discovered later, this step is not necessary because the compiler creates the necessary file invisible.

问题解决了,我之前.h在我的Objective-C类中创建并包含了一个名为的新文件,<ProductModuleName>-Swift.h但是,正如我后来发现的,这一步不是必需的,因为编译器创建了不可见的必要文件。

Simply include <ProductModuleName>-Swift.hin your class and it should work.

只需包含<ProductModuleName>-Swift.h在您的班级中,它就可以工作。

回答by Svitlana

Yes Thanks

是啊谢谢

it is strange but it'll work

这很奇怪,但它会起作用

1) Add @objc  to  Swift class

2) Add in .m 
    #import "(ProjectName)-Swift.h"

3) Call from .h
    @class SwiftClass;

4)On SwiftClass 
   click "Command" + Left Click (Apple Documantation)

5) To see "-Swift.h" -> click "Command" + Left Click

App will generate the interface for this class in -Swift.h

App 会在 -Swift.h 中为这个类生成接口

Example: SWIFT_CLASS("_TtC10Project17220PLHelper") @interface PLHelper

示例:SWIFT_CLASS("_TtC10Project17220PLHelper") @interface PLHelper

  • (void)notifyForDownloading:(NSDictionary *)userInfo;
  • (instancetype)init OBJC_DESIGNATED_INITIALIZER; @end
  • (void)notifyForDownloading:(NSDictionary *)userInfo;
  • (instancetype)init OBJC_DESIGNATED_INITIALIZER; @结尾

回答by Anubhav Giri

Assume We have ProjectName "MyFirstProjectOnSwift" and swift class name "mySwiftClass" and objectiveC class is "MyObjectiveCLass"

假设我们有 ProjectName "MyFirstProjectOnSwift" 和 swift 类名 "mySwiftClass",objectiveC 类是 "MyObjectiveCLass"

Following steps are:-

以下步骤是:-

  1. Add #import "MyFirstProjectOnSwift-Swift.h" in "MyObjectiveCLass.m"

  2. Add @class mySwiftClass in MyObjectiveCLass.h;

  3. Then in MyObjectiveCLass.m

    mySwiftClass *myClass = [mySwiftClass new]; {Call Like This in any method wherever you want to call swift method.}

  4. [myClass methodName];

  1. 在“MyObjectiveCLass.m”中添加#import“MyFirstProjectOnSwift-Swift.h”

  2. 在 MyObjectiveCLass.h 中添加 @class mySwiftClass;

  3. 然后在 MyObjectiveCLass.m

    mySwiftClass *myClass = [mySwiftClass 新]; {Call Like This in any method where you want to call swift method.}

  4. [我的类方法名称];

回答by Darius Miliauskas

Check the -Swift.h file which has the import on your .m file in objective-C:

检查 -Swift.h 文件,该文件在 Objective-C 中对 .m 文件进行了导入:

#import <YourProjectName-Swift.h>

Click on that line, and left-click - Jump To Definition.

单击该行,然后左键单击 - 跳转到定义。

This file should be included automatically, not manually.

此文件应自动包含,而不是手动包含。

回答by Bryan P

If you're still not seeing your class even after importing <ProductModuleName>-Swift.h.

如果您在导入<ProductModuleName>-Swift.h.

Make sure that your class is subclassing a native class (e.g UIViewController) or at least if it's just a utility class, make it subclass NSObject. Your class should now show.

确保您的类是本地类(例如UIViewController)的子类,或者至少如果它只是一个实用程序类,请将其子类化NSObject。你的类现在应该显示。

回答by Kqtr

Little additional tip for anyone stumbling upon this post and for hwhom the other answers do not work: you might also have to declare your Swift class "public".

对于任何在这篇文章中绊倒的人以及其他答案不起作用的人来说,还有一点额外的提示:您可能还必须将 Swift 类声明为“公开”。

Example:

例子:

@objc public class MySwiftClass: NSObject {

@objc public class MySwiftClass: NSObject {

回答by Javier Calatrava Llavería

The recomended way for executing Swift code from Objective-C on projects that are being migrated from Obj-C to Swift is using Bridge/Proxy pattern.

在从 Obj-C 迁移到 Swift 的项目上从 Objective-C 执行 Swift 代码的推荐方法是使用桥接/代理模式。

  1. Implement the Bridge.
  1. 实施桥梁。

import Foundation

import Foundation

@objc class AnalyticsPropertyBridge: NSObject {

@objc class AnalyticsPropertyBridge: NSObject {

private var analytics: AnalyticsManager = AnalyticsManager()

@objc func refreshProperties() {

    self.analytics.set(AnalyticsProperty.clientType)
}

}

}

  1. Include the objC caller module in the umbrella file (Bridging-Header):
  1. 在伞文件(Bridging-Header)中包含 objC 调用程序模块:

#import "CallerModule.h"

#import "CallerModule.h"

  1. Finally in the caller .m file, two issues:
  1. 最后在调用者 .m 文件中,有两个问题:

3.a Import umbrella file:

3.a 导入伞文件:

#import "MyProject-Swift.h"

#import "MyProject-Swift.h"

3.b Call the bridge.

3.b 呼叫网桥。

[[AnalyticsPropertyBridge new] refreshProperties];

[[AnalyticsPropertyBridge new] refreshProperties];

Benefits: Your swift code will not get dirty with @objc because code is being called from Objc. As time goes by, the ObjC will be reduced in your project and finally the bride will be removed.

好处:你的 swift 代码不会被 @objc 弄脏,因为代码是从 Objc 调用的。随着时间的推移,你的项目中的 ObjC 会减少,最后新娘会被移除。