React Native

时间:2018-05-03 00:10:08

标签: objective-c swift react-native objective-c-swift-bridge

假设我有一个名为ExampleClass的课程。

说我然后写代码如下:

@objc(ExampleClass)
class ExampleClass: NSObject {
  @objc class func exampleFunc() -> Void {

  }
}

使用Objective-C文件头,如下所示:

#import <Foundation/Foundation.h>
#import <React/RCTBridgeModule.h>

@interface RCT_EXTERN_MODULE(ExampleClass, NSObject)
  RCT_EXTERN_METHOD(exampleFunc)
@end

然后我在我的React Native应用程序中使用它,如下所示:

console.log('exampleClass', React.NativeModules.ExampleClass);
console.log('exampleFunc', React.NativeModules.ExampleClass.exampleFunc)

第一个控制台日志会导致{exampleFunc: f} 第二个结果为undefined

调用该函数:React.NativeModules.ExampleClass.exampleFunc()导致应用程序崩溃:

  

异常&#39; exampleFunc不是公认的Objective-C方法。&#39;在使用params(

)在目标ExampleClass上调用setupLogger时抛出了

虽然只更改了Swift,但它的内容为:

@objc(ExampleClass)
class ExampleClass: NSObject {
  @obj func exampleFunc() -> Void {

  }
}

导致调用函数(当然,是)什么都不做。

如何公开类级变量?我正在尝试编写函数Swift,我正在使用类方法来模拟结构。

2 个答案:

答案 0 :(得分:2)

根据我自己的类似问题和此处的一些讨论,我相信问题是RCT_EXPORT_METHOD()仅适用于实例方法,而不适用于类方法:https://github.com/facebook/react-native/issues/2311

我的用例是尝试为Swift单例类桥接getInstance()方法。这是有问题的,因为当您从已用NativeModules.ExampleClass导出的javascript中引用RCT_EXTERN_MODULE()时,RN会单独调用init(),而您不希望单例({{1 }}参考:https://samwize.com/2017/02/09/calling-a-view-controller-function-from-react-native/

我发现实现此目标的最佳方法非常难看。我有一个虚拟包装器类,除了在单例上的调用方法外,什么也不做,这是我导出到Objective C(因此导出到React Native)的类。基本上是这样的:

init()

,然后在.m桥文件中:

@objc(StupidWrapperClass)
class StupidWrapperClass : NSObject {
    @objc(pseudoSingletonSomeMethod)
    public func pseudoSingletonSomeMethod() {
        let singleton = ActualClass.getInstance()
        singleton.someMethod()
    }
}

您也可以为类方法做类似的事情:

@interface RCT_EXTERN_MODULE(StupidWrapperClass, NSObject)

RCT_EXTERN_METHOD(pseudoSingletonSomeMethod)

@end

答案 1 :(得分:1)

我知道我参加聚会有点晚,但是我最近遇到了同样的问题,因此我使用了不同的方法来解决它。除了@thejoelpatrol在上面给出的答案外,另一种方法是将由react native创建的对象引用存储在您可以访问的某些static变量中。然后,我们可以随时使用变量访问由react-native创建的对象。

每当React Native尝试实例化该类时,它都会进入初始化。在init内部,我们可以保存对RN创建的对象的引用。

@objc public class MyClass {
    @objc public static var shared: MyClass?

    init() {
        MyClass.shared = self
    }
}

.m桥文件如下:

@interface RCT_EXTERN_MODULE(MyClass)

RCT_EXTERN_METHOD(myClassMethod)

@end