GithubHelp home page GithubHelp logo

pinqy520 / react-native-webview-invoke Goto Github PK

View Code? Open in Web Editor NEW
236.0 10.0 44.0 453 KB

Invoke functions between React Native and WebView

License: MIT License

JavaScript 51.57% Java 15.82% Objective-C 10.75% HTML 7.23% Starlark 1.48% Ruby 13.15%
react react-native hybrid webview native invoke jsbridge bridge

react-native-webview-invoke's People

Contributors

dicklwm avatar pinqy520 avatar sridhardvvce avatar yjose avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

react-native-webview-invoke's Issues

RN层如何主动调用webview

你好,请问RN层怎么主动调用webview中的方法?或者说RN层可以主动向webview中提交数据么?

no way to work with

cannot invoke anything. syntax is obscure, no editor, even compiler cannot solve that syntax. A and B confusion (can be native and browser), is it compiled from TypeScript? Should be ts files included.

iOS RN调用webView方法的一点问题

感谢分享,
首先说明这并不算这个RN插件的问题,只是在使用这个插件的时候遇到的使用上的问题,
webView中绑定的方法最后会更改 window.location.href 原地刷新页面,
安卓版没有任何问题,
然而iOS版的话,不会自动去更新页面,
怀疑时iOS的WebView相关设定的问题,
有遇到过类型情况么?
非常感谢

hooks 组件件 push一个新的webview返回旧的webview,旧webview invoke定义的原生方法丢失

import { StackHeaderOptions } from '@react-navigation/stack/lib/typescript/src/types';
import React, { useCallback, useContext, useEffect, useRef } from 'react';
import {
View,
Platform,
StatusBar,
Keyboard,
BackHandler,
KeyboardEvent,
NativeModules,
StatusBarStyle,
AppState,
AppStateStatus
}
from 'react-native';
import { _openCamera, _openPicker } from '../../moudles/tokenPhoto';
import WebView from 'react-native-webview';
import createInvoke, { IMessager } from 'react-native-webview-invoke/native';
import { _testwebviewUrl } from '../../config/url';
import askPermission from '../../moudles/AskPermission';
import { getLocation } from '../../moudles/Location';
import JPush from 'jpush-react-native';
import styles from './indexstyle';
import { StoreContext } from '../../store';
import LoadError from '../../components/LoadErr';
import { useFocusEffect, useIsFocused } from '@react-navigation/native';

let statusBarHeight: number | undefined = 20;

const _PLATFROM = Platform.OS;

if (_PLATFROM === 'ios') {
NativeModules.StatusBarManager.getHeight((s:any) => {
statusBarHeight = s.height;
});
}
else statusBarHeight = StatusBar.currentHeight;

function Home(props:any) {

const webviewRef = useRef<WebView<{}>>(null);
const Invoke: IMessager = createInvoke(()=>webviewRef.current); // 创建注入原生方法的实列
const { state } = useContext(StoreContext);
const isFocused = useIsFocused();

const _keyboardDidShow:(e:KeyboardEvent)=>void = (e) => {  // 键盘弹起
    const js = ` window.keyboardDidShow && window.keyboardDidShow(${ e.endCoordinates.height })`;
    webviewRef.current && webviewRef.current.injectJavaScript(js);
};
const _keyboardDidHide:()=>void = () => {  // 键盘收起
    const js = 'window.keyboardDidHide && window.keyboardDidHide()';
    webviewRef.current && webviewRef.current.injectJavaScript(js);
};
const _onBackHander:()=>boolean = ()=>{  // 物理返回键
    const js = 'window.onBackHander && window.onBackHander()';
    webviewRef.current && webviewRef.current.injectJavaScript(js);
    return true;
}
const _onAppState:(nextAppState:AppStateStatus)=>void = (nextAppState)=>{  //App前后台切换状态
    const currAppState = AppState.currentState;
    const js = `window.onAppState && window.onAppState(${currAppState},${nextAppState})`;
    webviewRef.current && webviewRef.current.injectJavaScript(js);
}
const _push = (url:string, data?:{[key:string]:any},headerOptions?:StackHeaderOptions):void=>{ // 打开一个新的webview
    console.log(99999)
   props.navigation.push('Home',{
       url,
       ...data,
       headerOptions
   })
};
const _pop = ()=>{ // 返回上一个路由栈
    props.navigation.goBack();
}
const _setBarStyle = (color:StatusBarStyle)=>{  // 设置状态栏字体颜色
    if(_PLATFROM == 'ios') NativeModules.Tools.setBarStyle(color);
    else StatusBar.setBarStyle(color);
}
const _getStatusBarHeight:()=>number | undefined = ()=>{  // 获取状态栏高度
    return statusBarHeight
};
const _exitApp:()=>void = ()=>{  // 退出app
    if(_PLATFROM == 'android') BackHandler.exitApp();
}
const _reload:()=>void = ()=>{  // 重新加载
    webviewRef.current?.reload();
}

useEffect(()=>{ //   定义注入webview的原生方法
    //  打开一个新的webview 
    Invoke.define('push',_push);
    //  回退路由栈
    Invoke.define('pop',_pop)  
    //  设置状态栏样式'default' | 'light-content' | 'dark-content';
    Invoke.define('setBarStyle', _setBarStyle);
    //  获取状态栏高度
    Invoke.define('getStatusBarHeight', _getStatusBarHeight);
    //  android  请求权限询问
    Invoke.define('askPermission', askPermission);

    // 选择相册
    Invoke.define('openPicker', _openPicker);
    // 拍照
    Invoke.define('openCamera', _openCamera);

    // 退出App
    Invoke.define('exitApp', _exitApp);
    // 重载
    Invoke.define('reload', _reload);
    // 定位
    Invoke.define('getLocation', getLocation);
 

},[]);

useEffect(()=>{  // 监听 (键盘 | 物理返回 | AppState | 推送监听)

    const keyboardDidShow = Keyboard.addListener("keyboardDidShow", _keyboardDidShow);
    const keyboardDidHide = Keyboard.addListener("keyboardDidHide", _keyboardDidHide);

    const backHander = BackHandler.addEventListener('hardwareBackPress', _onBackHander);

    AppState.addEventListener('change', _onAppState);

    JPush.addNotificationListener(res => {
        let {url} = res.extras || {url: null},
          type = res.notificationEventType;
        if (type == 'notificationOpened' && url) {
          let json = JSON.stringify({url: url});
          const js = ` window.recievedPushMessage && window.recievedPushMessage(${json})`;
          webviewRef.current?.injectJavaScript(js);
        }
    });

    return () => {
        keyboardDidShow.remove();
        keyboardDidHide.remove();

        backHander.remove();

        AppState.removeEventListener('change', _onAppState);
        JPush.removeListener(()=>{});
    };
},[]);
useFocusEffect(useCallback(()=>{
    if(!isFocused){
        const js = ` window.screenIsFocused && window.screenIsFocused()`;
        webviewRef.current?.injectJavaScript(js);
    }
    
},[isFocused]))
let _webviewUrl: string = state?.webviewUrl || ''
_webviewUrl = _testwebviewUrl;
return(
    <View
        style={ styles.container }
    >
        { _PLATFROM == 'android' ?  <StatusBar  translucent={true} backgroundColor={'rgba(255,255,255,0)'} /> : null }
        <WebView
            ref={ webviewRef }
            style={{flex: 1}}
            sharedCookiesEnabled={true}
            useSharedProcessPool={true}
            source={{uri: props.route.params?.url || _webviewUrl }}  
            onLoadEnd={() => {}}
            mixedContentMode={'always'} // compatibility
            startInLoadingState={true}
            textZoom={100}
            allowsInlineMediaPlayback={true}
            scrollEnabled={ props.route.params?.scrollEnabled || false }
            onMessage={ Invoke.listener }
            renderError={()=>(
                <LoadError setBarStyle={ _setBarStyle } reload={ _reload }/>
            )}
        />   
    </View>
    
)

}

export default Home;

define一个方法,返回Promise.reject(false),catch不到

复现过程

RN端 :

this.invoke.define('test', () => {return Promise.reject(false)})

WebView端:

window.WebViewInvoke.fn.test()
  .then(function(res){ console.log(res) })
  .catch(function(err){ console.error(err) })

这时候catch就不生效了,没有false的log

希望效果:

catch可以log出false

另外

this.invoke.define('test', () => {return Promise.resolve(true)})

是正常的,then是能正常打出true结果的

not worked in iframe

在iframe里加载invoke,调用native的方法不生效,是不是invoke.listener无法监听到iframe的window.postMessage方法

0

0

invoke.bind undefine

React 引入项目 后
import invoke from 'react-native-webview-invoke/browser'

用invoke.bind 出现 _browser2.default.bind is not a function

hooks bug?

let _refWebview = React.useRef()
let invoke = createInvoke(() => _refWebview.current)

React.useEffect(() => {
    // 暴露方法给 H5
  invoke.define('route', setRoute)
    return () => {}
  }, [])

return (
<WebView
          useWebKit
          ref={_refWebview}
          style={{ flex: 1 }}
          source={{ uri: config.h5 + route.params.uri, headers: { 'Cache-Control': 'no-cache' } }}
          automaticallyAdjustContentInsets={true}
          decelerationRate="normal"
          scrollEnabled={true}
          javaScriptEnabled={true}
          domStorageEnabled={true}
          onMessage={invoke.listener}
          nativeConfig={{ props: { flex: 1 } }}
          onLoad={syntheticEvent => {
            const { nativeEvent } = syntheticEvent
            console.log(`nativeEvent.url: ${nativeEvent.url}`)
          }}
          onLoadProgress={({ nativeEvent }) => {
            console.log(`nativeEvent.progress: ${nativeEvent.progress}`)
          }}
          onLoadStart={syntheticEvent => {
            // update component to be aware of loading status
            const { nativeEvent } = syntheticEvent
            console.log(`onLoadStart nativeEvent.loading: ${nativeEvent.loading}`)
          }}
          onLoadEnd={syntheticEvent => {
            // update component to be aware of loading status
            const { nativeEvent } = syntheticEvent
            console.log(`onLoadEnd nativeEvent.loading: ${nativeEvent.loading}`)
          }}
          onError={syntheticEvent => {
            const { nativeEvent } = syntheticEvent
            console.warn('WebView error: ', nativeEvent)
          }}
          onHttpError={syntheticEvent => {
            const { nativeEvent } = syntheticEvent
            console.warn(
              'onHttpError WebView received error status code: ',
              nativeEvent.statusCode
            )
          }}
          originWhitelist={['*']}
          allowFileAccessFromFileURLs={true}
          allowFileAccess={true}
          allowUniversalAccessFromFileURLs={true}
          allowingReadAccessToURL={'file://'}
        />
)

H5 那边 会报 invoke.fn.route is not function

运行案例无法通信,也没有任何报错 react native 0.39.2

首先感谢楼主的分享
我的项目使用:
react native 0.39.2,
react-native-webview-invoke 0.2.2
react: 15.4.1
我的问题是:运行案例画面显示没问题,就是无法通信,也没有报错,按钮也可以点击
我是直接拷贝你的文件到我的项目,html文件放在网络使用http链接,界面运行没有报任何错误,只是无法通信,
我将html放在本地localhost访问也无法通信

invoking functions didn't work on Android

Hi @pinqy520 thanks for the great work.

I am trying to test the package with the dev the project work as expected on IOS but look like the invoking system didn't work on android platform in case we are using the new react-native-webview

any thoughts?

请问Demo有最新的吗?

《1》我在真机上使用时调取RN 的封装的方法回馈很慢,例如调取我封装的拍照功能,就需要等个7,8秒
《2》文档上的写法和Demo的不一样咧
《3》RN怎样调取html的方法呢?

Access to this in react native

Hi, thanks for this lib !

i have one question, how i can retrieve this in react native function ?

this.Native.define('myFunc', this.myFunc)

After in the function

  myFunc() {
    console.log(this)
    // can't access to this component
  }

I have tried with .bind(this) but nothing work.

Have you a idea ?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.