将Swift桥接到React-Native时出现“is not a recognized Objective-C method”错误

41

我正在尝试将我的React-Native 0.33代码连接到一个超级简单的Swift方法,遵循这个指南,但是我得到的只是show: (NSString*) name is not a recognized Objective-C method

以下是我的代码:

SwitchManager.swift

import Foundation

@objc(SwitchManager)
class SwitchManager: NSObject {

  @objc func show(name: String) -> Void {
    NSLog("%@", name);
  }

}

SwitchManagerBridge.h

#import "RCTBridgeModule.h"

@interface RCT_EXTERN_MODULE(SwitchManager, NSObject)

RCT_EXTERN_METHOD(show:(NSString *)name)

@end

SwitchManager-Bridging-Header.h

#import "RCTBridgeModule.h"

然后在我的index.ios.js文件中,我使用import { SwitchManager } from 'NativeModules';导入SwitchManager并调用SwitchManager.show('One');。这就是错误发生的地方。

不确定出了什么问题。


那这样怎么样 import { NativeModules } from 'react-native'; var SwitchManager = NativeModules.SwitchManager;? - vonovak
@VojtaNovak 我想我也尝试过这个,但是它没起作用。我知道 SwitchManager.show 被定义了,因为我做了一个 console.dir,而且它被暴露出来了。 - Benjamin Netter
@VojtaNovak 刚刚尝试了,一样的。 - Benjamin Netter
4个回答

79

这是Swift 3的一部分更改,可以通过添加下划线来解决:

import Foundation

@objc(SwitchManager)
class SwitchManager: NSObject {

  @objc func show(_ name: String) {
    NSLog("%@", name);
  }

}

请参考Swift 3的0046提案:在所有参数中包括第一个标签建立一致的标签行为,该提案在Swift.org迁移指南的“一致的第一个参数标签”下指出。

基本上,Objective-C如何看待Swift方法已经随着Swift 3的推出而改变。

编辑:在Swift 4中仍然是这样的,请参考此处的文档,在省略参数标签下


1
这对我有用。我可以确认这适用于Swift 3和React Native 0.34.0-rc.0。 - Mike Cole
2
关于这个问题的另一个注释:我的方法有3个参数,因此我为每个参数添加了下划线。但是这样不起作用!您必须仅将其添加到非标记参数。 - John kendall
2
太好了!那个奇怪的下划线是怎么回事?有人可以解释一下吗? - Yaron Levi
请查看我上面提供的链接,了解苹果公司的0046提案。这基本上是因为Objective C可以有未命名的第一个参数,但是Swift现在在全局范围内都有命名的第一个参数。这个下划线只是通过具有显式的“未命名”参数来保持与现有库的兼容性。 - James Wang
1
谢谢,它有效。在Swift4和xcode 9.4.1中仍然存在这种情况。 - Leon
显示剩余6条评论

22

这个在我的Xcode 8.0和Swift 3中运行成功了。

@objc func openPresentedViewController(_ name: String,name1: String,name2: String){
}

_添加到未标记的成员中

RCT_EXTERN_METHOD(methodName:(NSString *)name name1:(NSString *)name1 name2:(NSString *)name2)

正如您所看到的,在 Objective-C 方法名称中,非标签参数需要在 Swift 方法中添加 _


1
也适用于Swift 5。 - Harish J
对我来说它没有起作用。我需要修改@objc声明为@objc(openPresentedViewController: name1: name2:)。 - Rajan Twanabashu
对我来说也适用于Swift 5。 - Guru Dev

3
我整天在解决这个问题。通过将Swift编译器设置为使用遗留版本(XCode 8更喜欢Swift 3),问题得到了解决,所以在:
构建设置 > 滚动到 '使用遗留的Swift语言版本' 设置为

这是不是意味着你不能使用 Swift 3?我也遇到了这个问题,但如果可能的话,我还是想使用 Swift 3。 - Mike Cole
1
@mike-cole 看看下面的代码。如果你一直遇到问题,看看下划线是否有所不同,因为这是 Swift 3 为了与 ObjC 方法兼容而进行的更改。它并不是每个人问题的原因(我因为另一个“不是已知的 Objective-C 方法”问题而来到这里),但我猜这是一个常见的问题。 - James Wang
7
这不应该成为被接受的答案,这只是一个解决方法。下面关于方法标签的解决方案才是实际解决问题的方法。 - Koen.

2

我曾经遇到过同样的错误,因为我在函数声明前忘记添加@objc修饰符


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接