4
4

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 3 years have passed since last update.

cordova-plugin-inappbrowserでシステムブラウザを起動する最善の方法?

Last updated at Posted at 2019-08-14

相変わらずのcordovaメモ。
ていうかcordova-plugin-inappbrowserのメモ。

ちなみに
cordova:9.0.0
inappbrowser:3.1.1

inappbrowserはデフォルトの動作でwindow.openを暗殺する。
それはいい。(シャア的な口調で)

だがしかし、問題なのは
「InAppBrowser内でクリックされたURLをシステムブラウザから起動したい」
場合だ。

ここで大問題が発生したので苦しんでいる人がいたときのために共有したい。
cordovaなんて使わねえよという方ばかりの世の中だとしたらPOISION。

#InAppBrowser内で"_blank"が効かない

そうなんです。
window.open(url, "_blank");しても効かないんです。
なんかそういう風になってるんでしょうね。
細かいこと知らんよ。

というわけで、InAppBrowserではなくネイティブ側からシステムブラウザを起動することに。
InAppBrowser→Cordovaのブラウザ→システムブラウザ的な感じ。

伝達には"message"イベントを使う。
具体的には


if(window.webkit && window.webkit.messageHandlers){

                var messageObj = {
                        "type": "newwindow"
                        , "data" : "https://xxxxxxxxx"
                };
                var stringifiedMessageObj = JSON.stringify(messageObj);
                webkit.messageHandlers.cordova_iab.postMessage(stringifiedMessageObj);
}

みたいな感じでアプリ側(local側?非InAppBrowser側)にメッセージを送ります。
処理してねイベント。

#InAppBrowserでのシステムブラウザの開き方

んで、システムブラウザはこうやって開く。

cordova.InAppBrowser.open('http://apache.org', '_system');

これは公式さんがいくらでも書いてくれてる。
https://github.com/apache/cordova-plugin-inappbrowser

しかしである。
残念な問題が一つある。多分ある。少なくとも自分の環境ではあった。
InAppBrowser.openをコールすると何故か既に起動中のInAppBrowserにくっつけていたイベントが吹っ飛ぶ。
つまり"message"イベントが動作しなくなる。
一度外部サイトをシステムブラウザで開くと、もう二度と外部サイトが開かないことになってしまう。
おそロシア。

window.open(url, "_blank")は使えない。
じゃあcordova.InAppBrowser.open('http://apache.org', '_system');の後にイベント定義しなおしたらいいやんと思ったけどダメ。
多分スレッドの都合だと思ってタイマーまで使ってイベント再定義してみたけど一度試したらダメだったし邪道っぽいからあきらめた。
別のInAppBrowserを立ち上げる…つまり複数のInAppBrowserを起動して一つはメインサイト、もう一つは外部サイトみたいな動きにしたかったけどダメ。(InAppBrowserって複数起動できないの?)
公式に書いてある"delete window.open"とかしてみたけどダメ。

1人日使って悩んだ。

答えは転がっていた。

↓神様
https://github.com/apache/cordova-plugin-inappbrowser/issues/315

つまり、javascript起動直後、devicereadyの発火前に、


//起動前に退避
var DefaultOpen = window.open;

function openwork(){
     DefaultOpen(url, "_blank");
}

とかしておけばいいだけだった。
解決策をありがとう。
そしてデフォルトの挙動殺すのはどうしても賛同できんなあ。

2020.07.02WkWebViewの対応及びInAppBrowser最新版4.0.0

ところで上記の話はin-app-browser3.1.1の話です。
WkWebView対応を行うため、先日inappBrowserを4.0.0に上げたところ、上記の動作が一切動きません。
死んだ。

結論から言うと、最新版ではこう。

cordova.InAppBrowser.open('http://apache.org', '_system');

なんだけど、これだと一度しか開けない。
本当に、一度別ブラウザで開いたら終わる。

なのでこうする。

this.Ref = cordova.InAppBrowser.open('http://apache.org', '_system');

//イベントを再定義してやる。これマジで。しかしソースは動作未確認なのでタイポしてたら赦してください。
this.Ref.addEventListener("message", function(){ /* */ });

なんかシステムブラウザ起動時にイベントの関連付けが別インスタンスに飛んでしまうらしい。
ウソだと言ってよママン。

見たことも聞いたこともないObjectiveCのコードを必死にデバッグしたよ…(*´Д`)
これ、6.0.1とかになったら再度動作しなくなるんじゃなかろうか…。

4
4
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
4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?