[翻译]Nativescript 中 Web 视图与 Android/IOS 的双向通信

English document From http://shripalsoni.com/blog/nativescript-webview-native-bi-directional-communication/

Nativescript 中 Web 视图与 Android/IOS 的双向通信

shripal编写 在Nativescript



Nativescript 提供跨平台的 web 视图 ui 元素。它为在我们的页面中显示 web 视图内容提供了服务。
但是, 如果您希望将一些数据发送到 web 视图或从 web 视图获取一些数据, 则需要为此编写特定于平台的代码。因此, 与其在每个应用程序中编写所有这样的代码, 不如有一个插件。对?

我已经创建了nativescript web 视图接口插件以实现此目的。您可以克隆演示应用程序, 以便快速入门使用此插件。

演示应用的输出如下所示:

Android

Ios

在这个演示应用程序中, 我们在 web 视图中有语言下拉列表, 我们可以在下拉菜单中添加新的语言和查询语言, 从本机侧面。每当选定内容发生更改时, 下拉列表也会向本机发出事件。

让我们理解一下, 这是如何工作的。

步骤 1: 插件的初始化

首先, 我们需要按照https://www.npmjs.com/package/nativescript-webview-interface#installation)中的指令安装插件.
一旦安装了插件, 让我们添加web-view元素到我们的页面。

main-page.xml

Xml

<Page xmlns="http://schemas.nativescript.org/tns.xsd" loaded="pageLoaded">
....
<web-view id="webView" src="~/www/index.html"></web-view>
....
</Page>

现在, 初始化插件, 在我们的main-page.ts文件。(在这里, 我使用的是文稿, 但您可以在https://github.com/shripalsoni04/nativescript-webview-interface-demo中查看 javascript 中的相关代码。)

main-page.ts

文稿

import {webViewInterfaceDemoVM} from ‘./main-view-model‘;
var webViewInterfaceModule = require(‘nativescript-webview-interface‘);
var oLangWebViewInterface;

export function pageLoaded(args){
    page = args.object;
    page.bindingContext = webViewInterfaceDemoVM;
    setupWebViewInterface(page)
}

/**
 * Initializes webViewInterface for communication between webview and android/ios
 */
function setupWebViewInterface(page: Page){
    var webView = page.getViewById(‘webView‘);
    oLangWebViewInterface = new webViewInterfaceModule.WebViewInterface(webView);
}

检查代码main-view-model供参考。

假设我们按照上面提到的安装说明复制了 web 视图的插件文件, 让我们将插件文件导入到我们的index.html

www/index.html

Html

<!doctype html>
<html>
    <body>
        <select id="knownLanguage">
            <option value="-1">----Select Language----</option>
        </select>
        <script src="./lib/nativescript-webview-interface.js"></script>
        <script src="./index.js"></script>
    </body>
</html>

一旦插件文件在 html 文件中导入, 我们就可以访问所有必要的 API, 从 web 视图与本机应用程序进行通信, 在window.nsWebViewInterface全局对象。

www/index.js

Javascript

(function(){
    // oWebViewInterface provides necessary APIs for communication to native app.
    var oWebViewInterface = window.nsWebViewInterface;
    var languageDD = document.getElementById(‘knownLanguage‘);

    function init(){

    }

    init();
})()

步骤 2: 从本机应用程序的下拉列表中加载语言

现在, 我们要加载在其中加载的一些默认语言的下拉列表。在加载 web 视图后, 我们可以通过使用默认语言向 web 视图发出事件来执行此项设置。

main-page.ts

文稿

function setupWebViewInterface(page: Page){
    ...
    // loading languages in dropdown, on load of webView.
    webView.on(WebView.loadFinishedEvent, (args: LoadEventData) => {
        if (!args.error) {
            loadLanguagesInWebView();
        }
    });
    ...
}

/**
 * Sends intial list of languages to webView, once it is loaded
 */
function loadLanguagesInWebView(){
    oLangWebViewInterface.emit(‘loadLanguages‘, webViewInterfaceDemoVM.lstLanguages);
}

让我们来处理loadLanguagesweb 视图中的事件。

www/index.js

Javascript

function init(){
    ...
    addNativeMsgListener();
    ...
}

/**
 * Registers handlers for native events.
 */
function addNativeMsgListener() {
    oWebViewInterface.on(‘loadLanguages‘, function (arrLanguages) {
        for (var i = 0; i < arrLanguages.length; i++) {
            addLanguageOption(arrLanguages[i]);
        }
    });
}

/**
 *  Adds language to dropdown options
 */
function addLanguageOption(language){
    var option = document.createElement(‘Option‘);
    option.text = language;
    option.value = language;
    languageDD.appendChild(option);
}

步骤 3: 在下拉菜单中更改语言时通知本机应用程序

要让本机应用程序知道, 每当在下拉列表中更改语言时, 我们需要从 web 视图中从选择更改中发出事件。

www/index.js

Javascript

function init(){
    ...
    languageDD.onchange = function(){
        sendSelectedValue(languageDD.value);
    }
    ...

    /**
     * Sends selected value to native app by emitting an event
     */
    function sendSelectedValue(selectedLanguage){
        oWebViewInterface.emit(‘languageSelection‘, selectedLanguage);
    }
}

我们需要在本机方面处理此事件, 以便对语言更改进行任何操作。

main-page.ts

文稿

function setupWebViewInterface(page: Page){
    ...
    listenLangWebViewEvents();
    ...
}

/**
 * Handles any event/command emitted by language webview.
 */
function listenLangWebViewEvents(){
    // handles language selectionChange event.
    oLangWebViewInterface.on(‘languageSelection‘, (selectedLanguage) => {
        webViewInterfaceDemoVM.selectedLanguage = selectedLanguage;
    });
}

步骤 4: 从本机的下拉列表中添加新语言

要在本机应用程序的下拉选项中添加新语言, 我们可以直接调用在 web 视图中处理此操作的 JS 函数。

main-page.xml

Xml

<GridLayout rows="50" columns="*, 70">
    <TextField id="txtLanguage" col="0" hint="Language" />
    <Button col="1" text="Add" tap="addLanguage" />
</GridLayout>

main-page.ts

文稿

/**
 * Adds language to webView dropdown
 */
export function addLanguage(){
    var txtField = <TextField>page.getViewById(‘txtLanguage‘);
    oLangWebViewInterface.callJSFunction(‘addNewLanguage‘, [txtField.text]);
}

在这里, 我们打电话给addNewLanguageweb 视图的功能, 直接从本机应用程序. 请注意, 我们要传递给的参数addNewLanguage功能必须是数组格式。
由于我们不期望在 web 视图中的语言添加操作有任何返回值, 所以我们不需要将任何回调函数赋给callJSFunctionApi。

让我们创建addNewLanguage在 web 视图中的函数来处理此操作。

www/index.js

Javascript

function init(){
    ...
    defineNativeInterfaceFunctions();
    ...
}

/**
 * Defines global functions which will be called from andorid/ios
 */
function defineNativeInterfaceFunctions(){

    /**
     *  Handles new language addition initiated by native app
     */
    window.addNewLanguage = function(language){
        addLanguageOption(language);
        languageDD.value = language;
        languageDD.onchange();
    };
}

步骤 5: 从 web 视图查询数据

现在, 我们希望从 web 视图中获取当前选定语言的值。我们可以通过将 JS 函数调用到 web 视图来做到这一点。

main-page.ts

文稿

/**
 * Fetches currently selected language of dropdown in webView.
 */
export function getSelectedLanguage(){
   oLangWebViewInterface.callJSFunction(‘getSelectedLanguage‘, null, (oSelectedLang) => {
        alert(`Selected Language is ${oSelectedLang.text}`);
    });
}

www/index.js

Javascript

function defineNativeInterfaceFunctions(){
    ...
    window.getSelectedLanguage = function(){
        var selectedLangOpt = languageDD.options[languageDD.selectedIndex];
        return {id: selectedLangOpt.value, text: selectedLangOpt.text};
    };
    ...
}

步骤 6: 从 JS 功能调用的 web 视图返回延迟结果

根据 javscript 的异步性质, 有时我们不能在 web 视图中立即返回 js 函数的调用, 因此在这种情况下, 我们可以在 js 函数调用上返回一个承诺。
因此, 每当承诺得到解决, 在本机应用程序端注册的回调函数将用承诺的解析值来调用。

main-page.ts

文稿

/**
 * Fetches currently selected language of dropdown in webview.
 * The result will come after 2s. This function is written to show the support of deferred result.
 */
export function getSelectedLanguageDeferred(){
   oLangWebViewInterface.callJSFunction(‘getSelectedLanguageDeferred‘, null, (oSelectedLang) => {
        alert(`Deferred Selected Language is ${oSelectedLang.text}`);
    });
}

www/index.js

Javascript

function defineNativeInterfaceFunctions(){
    ...
    window.getSelectedLanguageDeferred = function(){
        var selectedLangOpt = languageDD.options[languageDD.selectedIndex];
        return new Promise(function(resolve) {
            setTimeout(function(){
                resolve({id: selectedLangOpt.value, text: selectedLangOpt.text});
            }, 2000);
        });
    };
    ...
}

我知道这是非常琐碎的应用程序, 但我发现这个应用程序是正确的解释所有的方案, 可以处理 nativescript-webivew 接口插件。
我还创建了一个服务于有效用例的应用程序。我将在将来发布它。

原文地址:https://www.cnblogs.com/anorthwolf/p/8985133.html

时间: 2024-11-09 04:00:50

[翻译]Nativescript 中 Web 视图与 Android/IOS 的双向通信的相关文章

改变mvc web api 支持android ,ios ,ajax等方式跨域调用

公司一个移动后端的项目用到了 webapi 项目搭建到外网环境共app开发者调用测试接口时遇到了一个问题 接口不允许跨域调用 .查阅资料明白 同源策略原则根据请求报头值 Origin 与回应报头值 Access-Control-Allow-Origin 来判断是否允许调用 解决方法 1.ajax使用jsonp jsonp 是通过请求参数中加入回调函数参数值.webapi 收到回调函数参数值返回数据不再是单纯的json,而是根据回调函数参数值 的js方法调用,这样就避免的同源策略 需要webapi

在webView 中使用JS 调用 Android / IOS的函数 Function

最近做一个项目,混合了NativeCode 和 HTML,为了便于JS 调用App的一些方法,统一封装一个Js方法,记录如下 Android 端首先要再WebView中允许JS的调用 WebView myWebView = (WebView) findViewById(R.id.webview); WebSettings webSettings = myWebView.getSettings(); webSettings.setJavaScriptEnabled(true); myWebView

仿各种APP将文章DOM转JSON并在APP中以列表显示(android、ios、php已开源)

背景 一直以来都想实现类似新闻客户端.鲜城等文章型app的正文显示,即在web editor下编辑后存为json,在app中解析json并显示正文. 网上搜过,没找到轮子.都是给的思路,然后告知是公司项目不好分享代码,所以干脆就自己做. 例子给的ui很粗,以实现功能为目的,你要有兴趣可以star等我更新. 输出的效果看起来是如上图所示.包括web的编辑器.ios.android.没做ui美化. 原理 web端 只是为了验证功能,所以信息包括标题.内容.其他数据都是模拟的,输出的json格式看起来

Android程序中Web页面和NativeCode交互

首先应该在AndroidManifest.xml把下面这个加上使得具有网络访问权限 <uses-permission android:name="android.permission.INTERNET"/> 然后在布局文件上插入WebView main.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http:/

Swift - iOS中各种视图控制器(View Controller)的介绍

在iOS中,不同的视图控制器负责不同的功能,采用不同的风格向用户呈现信息.下面对各个视图控制器做个总结: 1,标准视图控制器 - View Controller 这个控制器只是用来呈现内容.通常会用来作为子类,以向屏幕中添加逻辑. 2,导航控制器 - Navigation Controller 这个控制器呈现一个视图控制器的栈,应用程序可以在上面推入更多的视图控制器. 当新视图推入栈,或旧视图弹出栈时,导航控制器会以动画的形式(比如卷动)显示隐藏这些视图. 使用样例:系统“设置”应用程序 3,表

IOS中标签视图和Block

标签视图控制器 - UITabBarController 自定义UITabBarItem 自定义导航栏和标签栏背景图片 三个视图控制器的综合使用 一. 标签视图控制器  UITabBarController UITabBarController有以下重要属性 viewControllers   显示的视图控制器 tabBar                  标签栏 delegate                协议 tabBar 是 UITabBar对象, 包含多个UITabBarItem,

浅谈iOS中的视图优化

引言: 让我们来思考几个问题,你开发过的产品,它还有可以优化的地方吗?能增加它的帧率吗?能减少多余的CPU计算吗?是不是存在多余的GPU渲染?业务这点工作量对于越来越强大的设备面前显得微不足道,但作为一个细心的开发者,我觉得很有必要来谈谈iOS中的视图优化. 本文从开发者最容易犯错的地方出发,结合例子,从以下几个角度阐述如何进行视图优化: Color Blended Layers Color Copied Images Color Misaligned Images Color Offscree

Android中自定义视图View之---前奏篇

前言 好长时间没写blog了,心里感觉有点空荡荡的,今天有时间就来写一个关于自定义视图的的blog吧.关于这篇blog,网上已经有很多案例了,其实没什么难度的.但是我们在开发的过程中有时候会用到一些自定义的View以达到我们所需要的效果.其实网上的很多案例我们看完之后,发现这部分没什么难度的,我总结了两点: 1.准备纸和笔,计算坐标 2.在onDraw方法中开始画图,invalidate方法刷新,onTouchEvent方法监听触摸事件 对于绘图相关的知识,之前在弄JavaSE相关的知识的时候,

Android中自定义视图View之---开发案例

自定义视图View的案例 下面我们就是开始正式的进入自定义视图View了 在讲解正式内容之前,我们先来看一下基本知识 1.我们在自定义视图View的时候正确的步骤和方法 1).必须定义有Context/Attrbuite参数的构造方法,并且调用父类的方法 public LabelView(Context context, AttributeSet attrs) 不然会报错: 2).重写onMeasure方法 @Override protected void onMeasure(int width