Maison / Technologie / Fixer postMessage de React Native WebView pour iOS.

Fixer postMessage de React Native WebView pour iOS.

Suivre
( 0 Abonné(e)s )
X

Suivre

E-mail : *
Fixer postMessage de React Native WebView pour iOS. 1 jIDLAp j mv 0q ZSbmcnA
L'erreur qui n'aurait jamais dû être.

En 2016, l'utilisateur de GitHub, Robert Roskam (raiderrobert) a ouvert un numéro sur le référentiel React Native signalant l'erreur "La définition de onMessage sur une vue Web annule les valeurs existantes de window.postMessage, mais une valeur précédente a été définie". Au cours des deux dernières années, rien n’a été fait pour résoudre le problème dans l’implémentation interne de WebView de React Native.

La communauté autochtone React a WebView fourchue spécifiquement de le maintenir en tant que package tiers et de résoudre bon nombre de ces problèmes en cours. Toutefois, pour implémenter ces packages tiers, vous devez être en mesure de lier les packages natifs de React – lien réactif-natif react-natif-webview. Si vous êtes capable et disposé à le faire, votre problème est résolu. Les instructions d'installation pour l'édition communautaire de WebView sont aussi simples que:

fil ajouter https://github.com/react-native-community/react-native-webview
lien réactif-natif réaction-natif-webview

Remarque: Pour pouvoir réagir au lien natif …, vous devez d’abord ajouter le fil global et ajouter réact-natif.

Malheureusement, si vous ne pouvez pas ou ne voulez pas faire cela, il n’ya tout simplement aucune solution à ce problème. Pendant des années!

Les utilisateurs d'Expo, par exemple, devraient éjecter leur projet et écrire leur propre implémentation native, non-JavaScript. Théoriquement, Expo utilisera ces packages d’édition communautaire dans les prochaines versions; mais avec une fenêtre de lancement à quelques semaines à peine, mon équipe et moi-même n'étions pas disposés à attendre.

La solution

Si vous vous souciez plus de résoudre ce problème maintenant que la façon dont cela fonctionne, cette section est pour vous.

Npm install rn-webview –save ou yarn ajoutez rn-webview pour ajouter le package rn-webview à votre projet.

Où que vous utilisiez import {WebView} de & # 039; react-native & # 039;, remplacez-le simplement par import WebView depuis & # 039; rn-webview & # 039 ;. Ensuite, utilisez simplement le nouveau composant WebView comme vous le feriez avec l’implémentation interne React Native, y compris l’utilisation de l’application onMessage. Le paquetage rn-webview est juste un emballage pour l’implémentation interne React Native qui intercepte les messages via un canal différent de l’application interne onMessage, mais le gère avec son propre accessoire onMessage, donnant l’illusion que vous utilisez réellement l’onMessage interne avec les résultats attendus. résultats.

Mises en garde ?

Le paquetage rn-webview fonctionne en dirigeant le trafic window.postMessage vers history.pushState. Bien que l’implémentation iOS de React Native ne puisse pas gérer window.postMessage correctement, elle peut gérer les modifications de l’état de la navigation. De ce fait, l'événement de changement d'état de navigation est le canal par lequel les messages sont transférés entre WebView et l'application native.

Si la manipulation de l'état de l'historique est un aspect important de votre application, cette solution peut ne pas répondre à vos besoins. Ne hésitez pas à bifurquer le projet sur GitHub proposer des solutions alternatives. Les demandes de tirage et les numéros sont les bienvenus!

La mise en œuvre ?

Exporter

Tout d’abord, l’arbitre de WebView est particulièrement important. De ce fait, nous ne souhaitons pas que l’utilisateur perde l’accès à ce dernier. Nous commençons le package avec une implémentation forwardRef, où WebViewPostMessage est le nom de classe utilisé pour ce package.

https://medium.com/media/0229abcfc80a633dbfb83d578ef89039/href

Rendu

La sortie de ce composant sera l'implémentation interne de WebView de React Native en interne, avec quelques ajustements. Nous ne lui donnerons pas l’élément forwardedRef, car il n’est utilisé que pour donner au parent un accès à la référence et n’a aucun sens pour la WebView interne. Plus important encore, nous ne lui donnerons pas l’application onMessage, car c’est la source de tous nos problèmes – elle n’est pas prise en charge par iOS!

https://medium.com/media/e6a0f829237ad97e5d35cbef78460625/href

Nous avons un écouteur de changement d'état de navigation personnalisé, car c'est le canal par lequel nous allons écouter les messages.

Nous avons un gestionnaire de référence personnalisé, car nous avons tous les deux 1) besoin d'y accéder à l'intérieur de ce composant et 2) de renvoyer la référence au conteneur parent via le prop forwardedRef.

Ref

Lorsque la WebView interne nous donne sa référence, nous la stockons sur l'instance (this.ref = ref) pour une utilisation ultérieure. Si le parent a également demandé le renvoi, nous le transmettons.

https://medium.com/media/31d3d77378b7f2b086374b3df2096aae/href

Injectez window.postMessage

Désormais, une implémentation personnalisée de window.postMessage doit exister sur n'importe quelle page de WebView. Chaque fois que l'état de navigation change, si le chargement est terminé, nous y injectons du code JavaScript pour remplacer ce que window.postMessage fait.

https://medium.com/media/d155a2b670e3062be6293ef9edbf8457/href

J'ai défini et importéInjectPostMessage à partir d'un fichier différent pour la lisibilité.

https://medium.com/media/5b9e92d303618a79ffccc761f1f45fa5/href

C'est un expression de fonction immédiatement invoquée pour vous assurer qu'aucune de nos variables n'entre en conflit avec la page Web.

EMPTY_STATE est ce qui est poussé dans l'historique, car nous n'utiliserons pas d'objet d'état pour notre écouteur d'événement.

La fonction d'échappement échappe les apostrophes d'une chaîne afin que nous puissions placer cette chaîne dans des apostrophes. Dans la mesure où l'état de navigation que nous poussons n'est pas un code JavaScript réel et qu'il ne sera pas transmis à un interprète JavaScript, cette étape n'est pas exactement nécessaire. Cela permet simplement à l'état que nous poussons d'imiter de plus près le vrai JavaScript.

La variable postMessage vérifie si une fonction postMessage existe déjà. Si tel est le cas, nous voudrons l’exécuter également lors des appels window.postMessage.

Nous définissons notre propre fonction window.postMessage. La première chose à faire est d'exécuter la fonction window.postMessage précédente, si elle existait.

Ensuite, nous poussons à l'état d'historique. Nous n’avons pas d’objet d’état, nous utilisons donc le vide susmentionné. Le titre du document ne change pas, nous utilisons simplement le titre actuel. De plus, l'emplacement du document ne change pas en soi: nous ajoutons simplement un hachage.

Ce hash, que nous écouterons plus tard, est window.postMessage (& # 039; le message & # 039;). Il ressemble à du JavaScript, par conception, mais ne sera pas évalué par un interprète JavaScript réel. Nous avons simplement besoin d’un hachage unique qui ne se heurtera pas à de véritables hachages dans le document.

postMessage Listener

Maintenant que nous avons notre propre émetteur d’événement window.postMessage, nous devons l’écouter. C'est le code qui se trouve en haut de la méthode handleNavigationStateChange.

https://medium.com/media/5c955b6b599e048cd4ef01957c9d9fe7/href

Nous vérifions si la nouvelle URL correspond au hachage postMessage que nous avons défini précédemment. Si tel est le cas, nous allons revenir afin que le reste de l'écouteur d'événements de changement d'état de navigation ne soit pas déclenché. Il s’agit d’un événement de message et non d’un changement d’état de navigation.

Chaque événement postMessage déclenche le changement d'état de navigation deux fois – une fois pour le chargement: vrai et un presque immédiatement après pour le chargement: faux. Nous n'écoutons que l'événement loading: true, car il se produit en premier. L'événement loading: false est ignoré, car il s'agit simplement d'un doublon.

Uniquement si le composant parent a passé un gestionnaire d'événement onMessage, nous appelons ce gestionnaire avec un événement fictif contenant le message. Nous échappons le message avant de le transmettre, car nous avions échappé aux apostrophes plus tôt.

La fonction unescape est définie en haut du document, car elle est constante (ne dépend pas de l'instance) et n'a pas besoin d'être une méthode du composant. Vous pouvez l'importer si vous préférez le scinder en code.

https://medium.com/media/ce9cd15f670dd5f314cfa537c3f691fe/href

onNavigationStateChange

Ce qui précède couvre tout ce dont nous avons besoin pour intercepter window.postMessage et le gérer avec son propre écouteur d’événement onMessage. Notre problème initial est déjà résolu – onMessage fonctionne avec cette WebView. Cependant, puisque nous avons écrasé l'écouteur interne onNavigationStateChange, le parent ne reçoit plus d'événements de changement d'état de navigation.

Au bas de l'écouteur d'événement handleNavigationStateChange, ajoutez les éléments suivants:

https://medium.com/media/1f021443f9ddc75fe57ad900b5e2b2bb/href

Si le parent a inclus une propriété onNavigationStateChange, appelez-la et donnez-lui cet événement de changement d'état de navigation.

Le retour vide est simplement une préférence personnelle – je ne pense pas que les fonctions doivent retourner sous condition, même si cela équivaut fonctionnellement à un retour implicite.

Conclusion

Pour rappel, vous pouvez inclure le composant que vous venez de décrire en installant le package rn-webview de NPM. Vous pouvez aussi fourche-le sur GitHub. Les questions et demandes de tir sont les bienvenues.

Si vous avez aimé cet article, n'hésitez pas à lui applaudir une ou deux fois. C’est rapide, facile et gratuit! Si vous avez des questions ou des commentaires pertinents, veuillez les laisser dans les commentaires ci-dessous.

Pour lire plus de mes colonnes, vous pouvez me suivre sur LinkedIn et Gazouillement, ou Découvrez mon portfolio sur CharlesStover.com.

Fixer postMessage de React Native WebView pour iOS. stat event post


Fixer postMessage de React Native WebView pour iOS. a été publié à l'origine dans Hacker midi sur Medium, où les gens poursuivent la conversation en soulignant et en répondant à cette histoire.



Source

A propos newstrotteur-fr

Découvrez également

Spotify s’associe à Disney sur un nouveau centre de diffusion en continu destiné aux familles Screen Shot 2019 07 17 at 11

Spotify s’associe à Disney sur un nouveau centre de diffusion en continu destiné aux familles

Suivre ( 0 Abonné(e)s ) X Suivre E-mail : * Suivre Ne plus suivre Dans …

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *