11
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ReactNativeのWebviewBridgeがどれくらいちゃんと動くか試してみた

Last updated at Posted at 2016-06-10

WebviewBridgeとは

ReactNativeに限らずiPhoneやAndroidなどさまざまなアプリケーションやソフトウェアでブラウザをコンポーネントとして使いたい場面は多い。
特にスマホアプリでは、ガワネイティブと呼ばれる外側をネイティブなアプリケーションとして開発して、内側の実装をウェブページとして実装することが多い。

そういう場合にアプリ内にブラウザをコンポーネントとして取り込んで、外側と内側で情報のやりとりやイベントの呼び出しなどを行うこと目的としてWebviewBridgeの実装が用意される。

ウェブサイトの開発の方が経験者が豊富とか、過去の資産をそのまま活かしたりできるという特徴もあるし、アプリのデプロイをしなくてもサーバ側で情報を変更するだけで表示を変えられるといったメリットがある。

実現方法

基本的にはブラウザ側のjavascriptとアプリ側のコードが簡単な文字列を送受信する形で実装されることが多い。何でもできると逆にセキュリティホールになる可能性が高いため基本的にはあまり複雑なことはできないのが一般的。

Androidやiosでもwebviewにjavascriptを呼び出してブラウザ側から値を取得するような処理は用意されている。

ReactNativeでは

ReactNativeの基本的なことは置いておいて、bridge可能な実装として下記がメジャー
https://github.com/alinz/react-native-webview-bridge

このサンプルコードをいじってみて挙動がどの程度正確か探ってみる。ちなみに、

npm i react-native-webview-bridge

でインストールされるバージョンはちょっと古いのでgithubを直接指定して使う必要がある。今回はサンプルアプリを弄りたいので

git clone git@github.com:alinz/react-native-webview-bridge.git

して、且つそのままだとサンプルのpackage.jsonのreact-nativeのverが低いので

"react-native": "^0.24.0",

に変更してからnpm iしました。

iPhoneの場合

サンプルコードを弄って、どの処理がどのタイミングで表示されるのかを確認するアプリを作成して、次の3つの項目について確認する。

  • WebBridgeが有効か?
  • urlのstateが変更したタイミングでページが更新されるか?
  • ネイティブ側と通信できるか?

Cursor_と_iPhone_6_-iPhone_6___iOS_9_3__13E230.png

  • DOMContentLoaded:ページの読み込みが終わったタイミング
  • Injection from Lib:ライブラリの内部実装でJSが注入されたタイミング
  • EventListen:ブラウザ側がJSが注入されたことを確認したタイミング
  • Injection from Lib End:JSの注入が完了したタイミング
  • Injection from app.js:React側から任意のJSが注入されたタイミング

iPhone実装を確認した限り想定通りに処理が進んでいることが確認できた。

Cursor_と_iPhone_6_-iPhone_6___iOS_9_3__13E230.png

加えて、一番上のログが'Test2'となっているがWebview内でstateをchangeする形でTest2というページに遷移しても問題なくBridge処理が進んでいることが確認できた。

  • hoge:ReactNative側の送信が押されたタイミングでブラウザ側に文字列'hoge'が通知されたタイミング

送信ボタンを押す度にhogeが表示されるのでBridgeが構築されていることも確認できた。

Androidの場合

Screenshot_2016-06-09-11-44-25.png

EventListenが表示されないのでブラウザ側にEventが発行されないことがわかる。これではブラウザ側から通信が可能かどうかの判断ができない。

Cursor_と_WebViewBridgeManager_java_—__Users_yositosi_public_node_react-native-webview-bridge_examples_SampleRN20.png

実装を確認すると、すでにwindow.WebViewBridgeが存在してjsの注入作業が進んでいないことがわかる。

Cursor_と_test_html_—SampleRN20—__Users_yositosi_public_node_react-native-webview-bridge_examples_SampleRN20.png

なぜ、そのようなことが起きてしまうのかは後々調べるとして、ひとまず処理を通過させるために、ページ側にwindow.WebViewBridge = null;を追加してページが読み込まれた瞬間にnullを突っ込んでみる。

Screenshot_2016-06-10-14-14-53.png

app.jsのタイミングがおかしいがとりあえずEventが発行されることは確認された。

Screenshot_2016-06-10-14-15-01.png

iPhoneと同様にhogeが出力されるのでアプリとwebview間でも通信できることは確認できた。

結論

ひとまず、window.WebViewBridge = null;をページ側に書いておこう。こうすればAndroidとiPhoneで動作するものは作れそう。ただし、まだそれでもAndroidは不安定な印象。
なぜそのようなことになるのかは、ライブラリについてはこれから調査していく。

続報を待て!

11
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?