web-dev-qa-db-de.com

Debuggen von WebView in React Native-Apps

Ich habe eine native React-App, die WebView zum Rendern einer HTML-Seite aus den Assets verwendet. Die Seite hat einige Javascript, die etwas verarbeiten. Das Problem ist, dass ich die console.log-Anweisungen in der Webansicht nicht sehen kann. Ich habe Chrome Remote Remote Debugging WebViews ausprobiert

So sieht der Code aus. Beachten Sie, dass ich für Android versuche, einige native Requisiten bereitzustellen, um das Debuggen zu ermöglichen.

import React from 'react';
import Expo from 'expo';
import { WebView } from 'react-native';

export default class App extends React.Component {

  render() {
    const htmlURL = Expo.Asset.fromModule(require('./assets/index.html')).uri;
    return (
      <WebView nativeConfig={{props: {webContentsDebuggingEnabled: true}}}  
      source={{uri: htmlURL}} />
    );
  }
}


const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

Alle Ideen, wie dies funktionieren könnte, werden sehr geschätzt.

26
Mohsin Shafique

Der einfachste Weg, um Ihr WebView in React Native) zu untersuchen, ist die Verwendung von Remote JS Debugger. Dies hat den zusätzlichen Vorteil, dass Sie entweder mit iOS oder Android arbeiten können Debuggen Sie einfach das JavaScript, das in Ihrer Anwendung ausgeführt wird.

Um die WebViews anzuzeigen, gehen Sie noch einen Schritt weiter und verwenden Sie Chrome's Remote Devices .

DevTools Chrome

Wenn Sie neben Ihrem Dokument, das dem zu debuggenden index.html Entspricht, auf Überprüfen klicken, werden in der Konsole alle Protokolle für dieses WebView angezeigt.

enter image description here

Ich habe ein <script> Innerhalb von index.html In das <header> Eingefügt, das nur Folgendes bewirkt:

console.log('This is showing in the console!')

In der Abbildung oben sehen Sie, wie sich das Gerät in den DevTools abmeldet, die das WebView untersuchen.

20
mootrichard

Nicht sicher, ob es für Ihren Fall relevant ist, aber wenn Sie auch für iOS entwickeln, können Sie dies auf einem Mac + iOS-Simulator (oder einem echten Gerät) ganz einfach tun. Am Ende erstellt ein React Native WebView eine native Webansicht (UIWebView unter iOS und eine WebView unter Android). Daher gilt auch hier jede Debugging-Methode, die für Web-Apps funktioniert.

  1. Auf Ihrem iOS-Simulator (oder Gerät): Öffnen Sie die Einstellungs-App -> Safari -> Erweitert -> Webinspektor einschalten.
  2. Öffnen Sie Safari auf Ihrem Mac und aktivieren Sie den Entwicklermodus in: Einstellungen -> Erweitert -> Entwicklermenü in der Menüleiste anzeigen (Kontrollkästchen unten).
  3. In Safari auf Ihrem Mac haben Sie jetzt das Menü "Entwickeln". Öffnen Sie es und finden Sie den Simulator oder Ihr angeschlossenes Gerät. Wenn Sie diesen Menüpunkt anzeigen, wird die aktuell geladene Seite angezeigt. Dies funktioniert für jede auf dem Gerät geladene Seite, unabhängig davon, ob sie in einer WebView in Ihrer App oder im Systembrowser angezeigt wird.
  4. Wenn Sie die Seite ausgewählt haben, können Sie mit Safari Web Inspector praktisch alles tun: Anzeigen aller geladenen Ressourcen, Netzwerkanforderungen, Hervorheben von Elementen, Konsolenprotokolle, Debuggen des JS-Codes und mehr.
13
Artal

Ich schlage vor, javascript's Konsolenmeldungen (console.log) und logcat von Android in einem logcat zu vereinigen, der mit [Monitor] angezeigt werden kann. ( https://developer.Android.com/studio/profile/am-basics .html ). Es kann hilfreich sein, Konsolenmeldungen und WebView-Meldungen an einem Ort zu haben, insbesondere wenn Sie Rennbedingungen/Zeitprobleme haben, um die Reihenfolge der Ereignisse zu sehen. Mit Monitor können Sie auch Filter anwenden, um auszuwählen, welche Nachrichten angezeigt werden. iOS-Benutzer können dies auch hilfreich finden.

Hier ist ein Beispiel:  enter image description here Weitere Informationen zum Anpassen von WebView in React Native (a ​​JavaScript library für das Erstellen von Benutzeroberflächen) finden Sie unter CustomWebViewManager und CustomWebView in React Native . Sie wird von Facebook, Instagram und einer Community verwaltet von einzelnen Entwicklern und Unternehmen " wiki ).

Info: WebChromeClient lässt Sie mit Javascript'sconsole.log("message") umgehen 
{via onConsoleMessage(ConsoleMessage cm)}, alert() und anderen Funktionen.

JavaScript-Konsolennachrichten abfangen:

//find or get your React Native webView or create a CustomWebView
WebView webView = (WebView) this.findViewById(R.id.webView1);

//by setting a WebClient to catch javascript's console messages:
// and relay them to logcat (view in monitor) or do what you want with them
WebChromeClient webChromeClient = new WebChromeClient() {
        public boolean onConsoleMessage(ConsoleMessage cm) {
            Log.d(TAG, cm.message() + " -- From line "
                    + cm.lineNumber() + " of "
                    + cm.sourceId() );
            return true;
        }
    });

webView.setWebChromeClient(webChromeClient);

Das Problem mit cross platform support ist die Virtual Machine und die zugehörige Sandbox . Ich denke, react-nativeversucht, sehr rein JavaScript zu sein (schlägt jedoch fehl, JavaScript als Sprache ist rein, die Implementierungen sind niemals (immer Kompromisse). Meine persönliche Präferenz für die plattformübergreifende Unterstützung ist Cordova .

4
Jon Goodwin

Sie können window.postMessage aus Ihrem WebView und der onMessage-Eigenschaft der WebView-Komponente verwenden:

In Ihrer HTML:

...
window.postMessage(stringMessage, '*');
...

In Ihrer reaktiven Komponente:

import React from 'react';
import Expo from 'expo';
import { WebView } from 'react-native';

export default class App extends React.Component {
  handleMessage = (event) => {
     console.log(event.nativeEvent.data);
  }
  render() {
    const htmlURL = Expo.Asset.fromModule(require('./assets/index.html')).uri;
    return (
      <WebView nativeConfig={{props: {webContentsDebuggingEnabled: true}}}  
      source={{uri: htmlURL}}
      onMessage={this.handleMessage}
      />
    );
  }
}


const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});
0
WebsByTodd