Links maken tussen een WebView en Native code

Links maken tussen een WebView en Native code

Afgelopen maand werkte ik voor een klant met vrij specifieke producteisen: ze wilden een native applicatie laten bouwen met een bepaalde kaart, namelijk dezelfde die ze op hun website gebruiken. Dat betekent voor mij twee dingen: ten eerste Javascript, ten tweede uitvinden hoe ik berichten ga sturen tussen de WebView waar de kaart in zal zitten, en de native code van de app.

Het probleem

We zitten eigenlijk met twee grote componenten: een WKWebView met de kaart en de native user interface. We willen berichten van de webview naar de code kunnen sturen om bijvoorbeeld bij het selecteren van een marker op de kaart een user interface element te laten zien, of naar een detailview te gaan. We willen ook vanuit de code met de webview kunnen communiceren, om bijvoorbeeld objecten toe te voegen aan de kaart.

De oplossing

Gelukkig komt al deze functionaliteit out of the box met WKWebView. We beginnen met het maken van een webview. Dit kun je met code doen of door hem simpelweg in de Interface Builder te slepen en er dan een outlet voor te maken. Wat we als eerste moeten doen is ervoor zorgen dat onze ViewController aan de eisen van de WKScriptMessageHandler en WKNavigationDelegate protocollen voldoet:

Vergeet niet de navigationDelegate van de webview in te stellen in viewDidLoad!

Top, onze webview is nu gemaakt en hij voldoet aan de benodigde protocollen. We komen hier later op terug, maar nu eerst een beetje Javascript!

Javascript

In Javascript moeten we eerst een paar functies maken om de inkomende berichten te verwerken tot een actie. Vervolgens maken we een functie om de juiste berichten naar de native code te sturen.

De addPerson functie kan nu gebruikt worden om vanuit de native context een naam en een leeftijd naar de WebView te sturen. De sendNameToNative stuurt een naam terug naar de native code.

De laatste stappen

We moeten een paar dingen doen in de loadView functie, dus deze overriden we. We stellen hier een paar eigenschappen in zodat de WebView luistert naar de callback vanuit javascript.

Het is mogelijk dat je hier een klein beetje moet spelen met het frame van de view, maar dit hangt af van hoe de rest van je views eruitzien.

Het laatste wat we moeten doen is een functie maken om ook echt een bericht naar Javascript te sturen.

Dit is het laatste stukje van onze puzzel. Wanneer we deze functie aanroepen voeren we de string uit als javascript. We kunnen dit nu gebruiken in functies zoals webView(_:didFinish:) om dingen naar de WebView te sturen wanneer deze klaar is met laden, of we kunnen het gebruiken wanneer iemand in de user interface op een knop drukt.

Onthoud dat wanneer je gebruikers iets in laat vullen dat je moet valideren of het veilige code is.

Wat nu?

Nu het fundament er ligt kun je zo ver gaan als je wilt:

  • De responses vanuit javascript verwerken in de native code, en hierdoor animaties of veranderingen in de user interface in gang zetten.
  • Meer handlers toevoegen om meerdere responses te kunnen verwerken.

Succes!

Dit artikel verscheen eerder in het Engels op: https://medium.com/@JillevdWeerd/creating-links-between-wkwebview-and-native-code-8e998889b503