首页 > 解决方案 > 从 ViewController 发送事件到 React-Native

问题描述

在 iOS 编程方面,我是一个完整的初学者。我有一个 React Native 应用程序,并且我已经建立了一个到 Swift 模块的本地桥。我想要实现的是能够从 React Native 启动原生 ViewController 页面,然后关闭 ViewController 并将包含数据的事件发送回 React Native。

我在以下文件中进行了编辑:

Brygga.m (My ObjC bridge between React-Native and Swift)
Bridge-Test-Bridging-Header.h (Bridging-Header file)
ConnectingFile.swift (My Swift classes and methods)

我有以下文件:

根据我阅读的教程,要将事件从本地发送到 React-Native,我们必须使用 RCTEventEmitter。但是我不能从 RCTEventEmitter 子类启动 ViewController,所以我做了两个类。

一个是 UIViewController 的子类,一个是 RCTEventEmitter 的子类。我已经成功启动了我的 ViewController,但是当尝试通过我的 RCTEventEmitter 类将 ViewController 中的事件数据发送回 React Native 时;我得到错误

“Bridge 没有设置。这可能是因为你在 Brygga 中显式合成了桥,尽管它是从 RCTEventEmitter 继承的。”

连接文件.swift

import Foundation

@objc(Connect)
class Connect: UIViewController, MiSnapWorkflowViewControllerDelegate{
  
  func didFinishWithResults(resultsDictionary: [String : Any]) {
    let event: brygga = Brygga()
    brygga.Finished(data: "Hello")
  }
 
  @objc func startViewController() {
    DispatchQueue.main.async {
      let vc = MiSnapWorkflowViewController.init(with: [.passport, .selfie])
      
      vc.delegate = self
      let navigationController = UINavigationController(rootViewController: vc)
      navigationController.modalPresentationStyle = .fullScreen
      
      let topViewController = UIApplication.shared.keyWindow?.rootViewController
      topViewController?.present(navigationController, animated: true, completion:     nil)
      
    }
  }
 
}

@objc(Brygga)
class Brygga: RCTEventEmitter {
 
  
  @objc
  func Finished(data: String) {
    sendEvent(withName: "onFinished", body: ["data": data])
  }
  
  override func supportedEvents() -> [String]! {
    return ["onFinished"]
  }

  override static func requiresMainQueueSetup() -> Bool {
    return true
  }
  
}

Brygga.m

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

@interface RCT_EXTERN_MODULE(Brygga, RCTEventEmitter)

RCT_EXTERN_METHOD(Finished)

@end

@interface RCT_EXTERN_MODULE(Connect, RCTViewManager)

RCT_EXTERN_METHOD(goToNative)

@end

BridgeTest-Bridging-Header.h

#import <React/RCTBridgeModule.h>
#import <React/RCTBridge.h>
#import <React/RCTEventDispatcher.h>
#import <React/RCTEventEmitter.h>
#import <React/RCTRootView.h>
#import <React/RCTUtils.h>
#import <React/RCTConvert.h>
#import <React/RCTBundleURLProvider.h>

#import <React/RCTViewManager.h>

我认为这可能与我如何从 ViewController 启动 RCTEventEmitter 类有关。这家伙有一个类似的问题,但我无法理解解决方案

在 Swift 中实现 RCTEventEmitter 但未设置桥接异常

标签: iosswiftobjective-creact-native

解决方案


我最终解决了它。这是从不扩展 RCTEventEmitter 的其他类发送事件的解决方案,例如,如果您喜欢我想从扩展 UIViewController 的类发送事件。

您的 Swift 网桥应包含以下内容:

  • 桥接器
  • RNEventEmitter.swift
  • MyViewController.swift (或您的任何其他类)

桥接器

@interface RCT_EXTERN_MODULE(RNEventEmitter, RCTEventEmitter)

RCT_EXTERN_METHOD(supportedEvents)

@end

RNEventEmitter.swift

@objc(RNEventEmitter)
open class RNEventEmitter: RCTEventEmitter {

  public static var emitter: RCTEventEmitter!

  override init() {
    super.init()
    RNEventEmitter.emitter = self
  }

  open override func supportedEvents() -> [String] {
    ["onFinished", "onPending"]      // etc.
  }
}

MyViewController.swift

  func sendEvent(_ name: String, body: [String : Any]) {
    RNEventEmitter.emitter.sendEvent(withName: name, body: body)
  }

然后从任何地方 sendEvent("onFinished", "Native process has finished!")

当然,你也需要在 React Native 端接收这个。我也可以展示你如何做到这一点;

应用程序.js

import {NativeModules, NativeEventEmitter} from 'react-native';

const {RNEventEmitter} = NativeModules;

const eventEmitter = new NativeEventEmitter(RNEventEmitter);

  eventEmitter.addListener('onFinished', res =>
    console.log(res.data),
  );

推荐阅读