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


相変わらずの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とかになったら再度動作しなくなるんじゃなかろうか…。