我的 react js 代码如何与现有的 Obj-C 逻辑交互?

Posted

技术标签:

【中文标题】我的 react js 代码如何与现有的 Obj-C 逻辑交互?【英文标题】:How my react js code can interact with existing Obj-C logic? 【发布时间】:2015-06-01 17:36:55 【问题描述】:

我现有的 Obj-C 项目具有丰富的业务逻辑。我想尝试在特定屏幕上使用 React Native(我的意思是 Cocoa 中的 View Controller),但是我在 repo 中看到的每个示例都包含 javascript 中的逻辑。如何将 React Native 视为渲染,但将用户操作传递给我的 Objective-C 代码?

2015 年 3 月 31 日编辑:

原生视图模块似乎不是一个好的解决方案,因为原生模块是从 React 代码实例化的。因此,如果我想为该视图控制器使用已经创建的视图模型,我需要有一些单例,这就像一个共享状态。我认为这很糟糕。

【问题讨论】:

【参考方案1】:

查看文档:

http://facebook.github.io/react-native/docs/nativemodulesios.html#content

React Native 提供“原生模块”作为连接 Obj-C 和 JavaScript 的一种方式。在 React Native 主页上还有更多关于此的内容:

http://facebook.github.io/react-native/

在“可扩展性”标题下,它显示了如何公开自定义 iOS 视图。

【讨论】:

是的,我确实阅读了那篇文档,但它的含义是原生模块不是用于应用程序逻辑,而是其中的一小部分,而 javascript 应该始终包含更高级别的逻辑。请参阅我更新的问题。【参考方案2】:

React 视图不可能在不通过 JavaScript 的情况下直接调用本机方法,除非您为屏幕上的所有内容创建自定义本机视图插件。

你最好的选择可能是创建一个自定义的原生模块,导出你想要调用的所有原生方法,然后编写一个最小的 React JavaScript 应用程序,除了通过调用这些方法将视图中的触摸事件转发到你的模块之外什么都不做。

如果您需要与 JS 应用程序进行通信,您的模块可以使用传递给导出方法的回调,或者广播 JS 代码可以观察到的事件。

不过,为了充分利用 React Native,我建议您尝试将所有视图和控制器逻辑保留在 JS 部分中,并且只从本机端公开业务逻辑。否则,您将失去快速重新加载以测试更改等的所有好处。

【讨论】:

我应该如何理解这一点?因为我的应用逻辑似乎不是onscreen,所以我不想把它放在javascript中。是的,我正在使用 MVVM,所以我想在 JS 中保留所有视图特性(阅读“拐杖”)和在 Obj-C 中保留纯逻辑。而且我在 Obj-C 中已经有了后者。请查看我的更新答案。 原生模块通常由 React 实例化,但是当您通过传递 moduleProvider 块设置 RCTBridge/RCTRootView 时,可以注入现有实例。因此,在您的情况下,您可以将预先分配的视图模型作为 RCTBridgeModule 或作为您创建的另一个 RCTBridgeModule 的属性传递。【参考方案3】:

我有同样的问题,我做了什么来解决它:

    围绕 NSNotificationCenter 创建 Native Module 包装器,以便 javascript 代码可以发布 iOS 事件。

    在 ReactController-wrapper 中围绕 React-Native 代码订阅该事件。

    当用户单击按钮时引发事件(当我们需要将控制权交还给 Objective-c 时),需要的数据作为字典传递。

    从 ReactController-wrapper (objective-c) 捕获事件,处理数据,打开其他控制器/等。

Using React Native within existing iOS app for some views only

【讨论】:

【参考方案4】:

如果您在视图控制器中实现 RCTRootView,则可以使用它来访问 RTCBridge,然后从中获得对模块的访问权限。

这将允许您在模块中保留对视图控制器的引用,从而使您能够直接将调用传递给方法,而不是依赖 NSNotifications。

示例:

在您的视图控制器中

    let reactView = RCTRootView(bundleURL: jsCodeLocation, moduleName: "MyReactApp", initialProperties: nil, launchOptions: nil)
    self.reactBridge = reactView.bridge
    let myModule = self.reactBridge.module(for: MYModuleClass.self) as! MYModuleClass
    myModule.viewController = self

并在您的模块中保留参考:

   @objc(MYModuleClass)
   class MYModuleClass: NSObject 

      weak var viewController: MyViewController!

   

【讨论】:

以上是关于我的 react js 代码如何与现有的 Obj-C 逻辑交互?的主要内容,如果未能解决你的问题,请参考以下文章

将 grunt 与现有的 wordpress 实例一起使用

RN与现有的原生app集成

如何将 Gatling 与现有的 Spring-Boot + Gradle 应用程序集成

我想将 LearnMoreButton 文本与 h4 文本对齐。与现有的,了解更多显示在下一行

如何将 Entity Framework Code First 与现有的 MS Access (.accdb) 数据库一起使用?

如何将 SCNRenderer 与现有的 MTLCommandBuffer 结合起来?