1. ホーム
  2. Web制作
  3. html5

Html5とAppの通信方式を解説

2022-01-14 07:28:18

プリアンブル

最近では、デスクトップとモバイルの両方のクライアントがH5ページの一部を挟み込んでおり、このようなハイブリッドアプリもよくHybrid Appと呼ばれるものです。なぜハイブリッドアプリが登場したのか?初期の頃は、AndroidやiOSのクライアントを開発するには大きな人件費と長い開発サイクルが必要だったため、ページの一部を分割してフロントエンドにやらせ、クライアントではWebviewで表示することで簡単にしたチームがあったためだそうです。

私は中途半端なプログラマーなので、フロントエンドの領域しか知らず、他のプログラミング領域との接点が少ないため、Webviewの実装原理やH5ページとのインタラクションについて探求することはありません。もし興味があれば、自分でJSBridgeに関する知識を検索したり、クライアントサイド(Windows、MacOS、Android、iOS)開発の学生にJSと他のプログラミング言語とのブリッジの方法を聞いてみるとよいでしょう。

長所と短所

何事にも良いところと悪いところがあり、絶対的な解はない。ここでは、開発プロセスにおけるハイブリッド・アプリの長所と短所をまとめましたので、ハイブリッド・アプリの良し悪しをご自身でご判断ください。

<スパン 長所

  • H5ページはフロントエンドで開発し、ページモジュールは別途開発・保守することで、アプリ開発サイクルを効果的に短縮することができます
  • H5ページは、アプリストアの面倒な審査プロセスや長い待ち時間に制限されず、新しいページや機能、不具合の修正をいつでもオンラインで展開することができます。
  • H5ページは必要な時に読み込まれるため、パッケージアプリのサイズが小さくなり、アプリストアでのダウンロードにかかる時間が短縮され、携帯電話のローカルに占める容量も小さくなる
  • H5ページはApp Webviewに接続され、ブラウザに制限されなくなるため、Appと相互作用してデバイスのより多くの基本APIを呼び出し、ブラウザが完了できなかったより多くの操作を改善することができます。

短所

  • H5とアプリ間の通信プロトコルに合意し、グローバルプロパティとグローバルメソッドの呼び出し方法を定義する。
  • App WebviewにH5ページを表示すると、フロントエンドとクライアントからより多くの注意を払う必要がある多くの互換性の問題がある可能性があります
  • 開発前に、要件やインタラクションに応じて、どのページがフロントエンドの開発に属し、どのページがクライアントの開発に属するかを分ける必要がある
  • ページのバグは時々エラーのどの部分で見つけることは困難である、あなたは問題がどこにあるかを見つけるために、フロントエンドとクライアントをデバッグする必要があります(独自のビューを持っているかもしれない、戦いはの一部である)。

通信方法

以下のコードはすべてデモ用のフロントエンド(React)をベースにしており、クライアントサイドがJSのインタラクションをどのように実装しているかについてはあまり語りませんので、クライアントサイド開発の学生を探すと理解できると思います。通信は以下の2通りで、どちらもJSのコードを使っていますが、それでも互換性はかなり高いです。

  • フロントエンドからクライアントへの通知:インターセプト
  • クライアントからフロントエンドへの通知:インジェクト

フロントエンドからクライアントへの通知

H5ページでリンクジャンプをトリガーすると、App Webviewはリンクジャンプを検出し、それをインターセプトするので、URL上にパラメータを運ぶことによって、次に何をすべきかをAppに伝えることができます。

import React, { Component } from "react";

export default class App extends Component {
    componentDidMount() {
        location.href = "lsbox://toast?msg=Page Loaded"; // Notify App
    }
    render() {
        return (
            <div className="app">
                <button type="button" onClick={this.openMask.bind(this)}> click it </button>
            </app>
        );
    }
    openMask() {
        location.href = "lsbox://mask?toggle=1"; // Notify App
    }
}



上記は、location.href = "lsbox://mask?toggle=1"を実行し、マスク層を開くようにアプリに通知しています。

  • lsbox: フロントエンドとクライアントがリンクジャンプのプロトコルを定義(プロトコルは自由に定義してください)
  • mask: アプリが実行する必要のあるアクション(好きなようにアクションを定義してください)
  • toggle=1: アクション実行パラメータ(アプリに何をするか指示するためのカスタムパラメータ)

2つ以上のlocation.hrefが同期してトリガーされる場合(次のlocation.hrefの次に前のlocation.href)、アプリは1つのlocation.hrefからの通知しか受け取れないことがあるので、 setTimeout Timeout(Async/Awaitラッパーを使って最適化できます)で次のlocation.hrefの通知を設定する必要があります。

location.href = "lsbox://toast?msg=one";
setTimeout(() => {
    location.href = "lsbox://toast?msg=two";
    setTimeout(() => {
        location.href = "lsbox://toast?msg=three";
    }, 100);
}, 100);


クライアントからフロントエンドへの通知

グローバルメソッドをいくつか注入し、App Webview はグローバルメソッドを直接操作して H5 ページを制御します。注入されたメソッドを定義するために window.handleFunc = function() {} のようなフォームを使用します。

import React, { Component } from "react";

export default class App extends Component {
    constructor(props) {
        super(props);
        this.state = {
            list: [0, 1, 2, 3, 4]
        };
    }
    componentDidMount() {
        window.addNum = this.addNum.bind(this); // expose the method to the App
    }
    render() {
        return (
            <div className="app">
                <ul>{this.state.list.map(v => <li key={v}>{v}</li>)}</ul>
            </div>;
        );
    }
    addNum(num) {
        this.setState(prevState => ({
            list: prevState.list.concat(num);
        }));
    }
}



上記により、コンポーネントが読み込まれた後、window.addNum = this.addNum.bind(this) により、指定されたメソッドがグローバルに window に公開され、App Webview はこれらのメソッドを直接操作して H5 ページを制御できるようになりました。

まとめ

今後も、H5とアプリのコミュニケーションで見落としていることを思い出したら、この記事に追記していきますので、記事のポイントを補足したり、ご自身の気づきを提供いただければと思います。

今回の記事は以上です。勉強になると思いますので、もっとScripting Houseを応援してください。