如何在Swift和React-Native之间建立桥梁

时间:2019-10-14 17:18:05

标签: ios swift react-native react-navigation react-native-ios

我目前正在为我正在从事的项目尝试新的东西。

我需要使用React Native创建一个视图,需要从我们的本机(Swift)应用中调用该视图。

这需要使用NavigatorBar。我按照我的需要遵循了不同的教程:

  1. Integrating React-Native in an existing iOS App:这使我可以按下VC并在屏幕上显示文本。

  2. 我创建了自己的NavigationBar,然后我考虑了如何在按下Button后关闭当前(RN视图),这是我找到另一个教程的时候:React-Native tutorial: Integrating in an existing app:这个本来应该允许我通过在Swift和RN之间建立桥梁来消除当前的VC,但是当我创建Navigation元素时,总是出现错误:

    Invariant Violation: Element type is invalid:
    expected a string (for built-in components) 
    or a class/function (for composite
    components) but got: undefined. You likely
    forgot to export your component from the file
    it's defined in, or you might have mixed up
    default and named imports
    
    Check the render method of `RNHelloWorld`.
    
    This error is located at:
      in RNHelloWorld (at renderApplication.js:40)
      in RCTView (at AppContainer.js:101)
      in RCTView (at AppContainer.js:119)
      in AppContainer (at renderApplication.js:39)
    

我实际上是React Native的初学者,那些教程有些过时了,但是我还没有发现其他需要更新的东西。

如何正确地在RN和Swift代码之间建立桥梁,以便能够使用TouchableOpacity消除按钮/文本上的屏幕?

这是我用于调用该屏幕的Swift代码的样子:

fileprivate func loadReactScreen() {
    let images = [UIImage(named: "closeIcon")?.pngData()?.base64EncodedString(),
                  UIImage(named: "image1")?.pngData()?.base64EncodedString()]

    let props: [String : [String?]] = [
        "images": images
    ]
    let rootView = MixerReactModule.sharedInstance.viewForModule("RNHelloWorld", initialProperties: props)

    let vc = UIViewController()
    vc.view = rootView
    self.present(vc, animated: true, completion: nil)
}

import Foundation
import React

class MixerReactModule: NSObject {
    static let sharedInstance = MixerReactModule()
    var bridge: RCTBridge?

    func createBridgeIfNeeded() -> RCTBridge {
        if bridge == nil {
            bridge = RCTBridge.init(delegate: self, launchOptions: nil)
        }
        return bridge!
    }

    func viewForModule(_ moduleName: String, initialProperties: [String : Any]?) -> RCTRootView {
        let viewBridge = createBridgeIfNeeded()
        let rootView: RCTRootView = RCTRootView(
            bridge: viewBridge,
            moduleName: moduleName,
            initialProperties: initialProperties)
        return rootView
    }
}


extension MixerReactModule: RCTBridgeDelegate {
    func sourceURL(for bridge: RCTBridge!) -> URL! {
        return URL(string: "http://0.0.0.0:8081/index.bundle?platform=ios") //IP address points to my localhost, hiding real one from question
    }
}

现在,我的React-Native代码看起来像这样:

index.js

import React from 'react';
import PropTypes from 'prop-types';
import {AppRegistry, NavigatorIOS, Text} from 'react-native'

export default class RNHelloWorld extends React.Component {
    render() {
        return (
            <NavigatorIOS
                initialRoute={{
                    component: MyScene,
                    title: 'Hello, World!'
                }}
            />
        );
    }
}

class MyScene extends React.Component {
    static propTypes = {
        title: PropTypes.string.isRequired,
        navigator: PropTypes.object.isRequired,
    };

    _onForward = () => {
        this.props.navigator.push({
            title: 'Scene'
        })
    };

    render() {
        return (
            <View>
                <Text>Current Scene: {this.props.title}</Text>
            </View>
        )
    }
}

// Module name
AppRegistry.registerComponent('RNHelloWorld', () => RNHelloWorld);

这是我在仅使用NavigatorIOS来使用Navigator之前所做的事情:

<Navigator
    initialRoute={{title: 'WOLOLO'}}
    renderScene={(route, navigator) => <Text>{route.title}</Text>}
    navigationBar={
        <Navigator.NavigationBar
            routeMapper={{
                LeftButton: null,
                RightButton: null,
                Title: (route, navigator, index, navState) =>
                { return (<Text>Awesome Nav Bar</Text>); }
            }}
            style={styles.navBar}
        />
    }
    style={{background: 'gray'}}
/>

如果我将navigationBar包含在Navigation组件中,则会收到不同的错误,但是删除它会显示与上述相同的错误。

TypeError: undefined is not an object
(evaluating '_reactNative.Navigator.NavigationBar')

This error is located at:
  in RNHelloWorld (at renderApplication.js:40)
  in RCTView (at AppContainer.js:101)
  in RCTView (at AppContainer.js:119)
  in AppContainer (at renderApplication.js:39)

我认为这里发生的是我的NavigatorIOS(或我的Navigator)为空,因为我不是从RCTRootView发送过来的,如果是这样,怎么办是吗?

0 个答案:

没有答案