web-dev-qa-db-ja.com

JavaScriptでWKWebView内にページが読み込まれているかどうかを検出する

JavaScriptを使用して、ページがWKWebView内に読み込まれていることを確実に検出するにはどうすればよいですか?これらのシナリオを検出できるようにしたい:

  • iOSおよびWKWebView
  • iOSおよびSafari
  • iOSではない

UIWebView here についても同様の質問があります。しかし、それはかなり古く、同じことがWKWebViewにも当てはまるかどうかはわかりません。

20
andr111

受け入れられた回答は WKWebView vs UIWebView app を使用してテストされたとおりに機能しません

記事で述べているように、HTML5機能の唯一の違いはIndexedDBのサポートです。だから私はより信頼性の高いパターンに行きます:

    if (navigator.platform.substr(0,2) === 'iP'){
      //iOS (iPhone, iPod or iPad)
      var lte9 = /constructor/i.test(window.HTMLElement);
      var nav = window.navigator, ua = nav.userAgent, idb = !!window.indexedDB;
      if (ua.indexOf('Safari') !== -1 && ua.indexOf('Version') !== -1 && !nav.standalone){      
        //Safari (WKWebView/Nitro since 6+)
      } else if ((!idb && lte9) || !window.statusbar.visible) {
        //UIWebView
      } else if ((window.webkit && window.webkit.messageHandlers) || !lte9 || idb){
        //WKWebView
      }
    }

あなたは尋ねるかもしれません:なぜUserAgentを使わないのですか?これは、Androidブラウザーが設定として使用するためです!したがって、UAを信頼することはできません。ブラウザーの機能とプロパティチェックだけがそのようなものです。

また、QuickTimeプラグインが常にUISViewのOlder Safariおよびその他のブラウザの一部としてロードされていることに気付きました。ただし、プラグインはWKWebViewに存在しません。したがって、QuickTimeプラグインの存在を追加のチェックとして使用できます。

9/23/16編集:Safari 10のコードを調整しました。@ xmnboyで言及されているように、唯一のIDBチェックの信頼性が失われました。 Safari 10を破棄するために、Safari 9.2までしか適用されなかった古いwebkitエンジンのバグをチェックします。と私はwindow.statusbar.visibleフォールバックは、iOS 9と10の間のいくつかの比較テストの後に信頼できるインジケーター信号であるように見えます(ただし、確認してください)

29
hexalys

IOS 10でAppleによって導入されたUIWebViewの動作の変更を考慮して、@ Justin-Michaelによる元の応答と@hexalysによるお気に入りのフォローアップを組み合わせた新しい回答を次に示します。

var isWKWebView = false ;
if( navigator.platform.substr(0,2) === 'iP' ) {    // iOS detected
    if( window.webkit && window.webkit.messageHandlers ) {
        isWKWebView = true ;
    }
}

ジャスティンの答えは、iOS 9とiOS 10の両方で機能するため、本当に優れた機能検出メカニズムでした。

IOS 11に到達したときに何が起こるかわかりません。


資格:公式Cordova WKWebViewプラグイン を使用してwebviewアプリをビルドしている場合、このプラグインは動作するため、このテストは機能しますこの投稿へのコメントの@hexalysで指摘されているように、addScriptMessageHandlerメソッドを初期化します。 Cordovaはこのメカニズムを使用して、WKWebViewプラグインが存在する場合に新しいJSをネイティブブリッジに定義します。

そのプラグインのリポジトリaddScriptMessageHandlerを検索し、そのリポジトリの the ios-wkwebview-exec.js file の最後を見て、実装の詳細を確認します(またはそのファイルの文字列window.webkit.messageHandlers)。

4
xmnboy

最新のiOS Chrome WKWebViewをレンダリングエンジンとして使用しているため、ChromeはWKWebViewとして検出されます。ua.indexOf( 'CriOS')!== -1は、Chrome=アプリ内のWKWebViewと区別するのに役立ちます。

0

IOSでは、次のコードを追加して、JavaScriptとObjective-C間の通信を確立できます。

WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
WKUserContentController *controller = [[WKUserContentController alloc] init];
[controller addScriptMessageHandler:self name:@"javascript_observer"];
configuration.userContentController = controller;

...

webview = [[WKWebView alloc] initWithFrame:... configuration: configuration];

JavaScriptでは、次のように接続をテストできます。

if ( window.webkit != undefined ){
//javascript is running in webview
}
0
Jarir