Titelbild Kommunikation JS-ObjectiveC

Kommunikation zwischen Objective-C und JavaScript ohne Frameworks

Von am 19.10.2013

Als Alternative zu rein nativ programmierten Applikationen und Web-Apps werden Hybrid-Apps immer beliebter. Sie enthalten Web Content eingebettet in einem nativen Container, um die Vorteile aus beiden Welten zu vereinen. Somit kann auf alle Gerätefunktionen wie zum Beispiel Kamera, Sensoren und Filesystem zugegriffen werden, während der Hauptteil der Applikation aus plattformübergreifendem Web Content, sprich HTML5, CSS3 und JavaScript, besteht.

Verschiedene Frameworks, wie zum Beispiel PhoneGap und Appcelerator Titanium Mobile, erleichtern die Erstellung des nativen Anwendungscontainers und die Verknüpfung der JavaScript-Funktionen mit den nativen Betriebssystemfunktionen.

Für die Developer mit Grundkenntnissen in Objective-C ist es aber auch möglich, eine Kommunikation zur UIWebView (native Browserkomponente unter iOS) ohne Framework herzustellen.

Dazu wird das „UIWebViewDelegate“-Protokoll implementiert, welches auf bestimmte Ereignisse, wie zum Beispiel das Laden einer URL innerhalb der Browserkomponente, reagieren und die aufgerufene URL auf bestimmte Schlüsselwörter durchsuchen kann. Dadurch kann die entsprechende native Funktion aufgerufen werden.

Hier ein Beispiel:

Im JavaScript:

Eine URL mit selbst gewähltem Schlüsselwort, beispielsweise anyKeyword, zusammenstellen und normal aufrufen:

Aufruf der URL in JavaScript

Die delegierende Klasse reagiert aber auch auf Ereignisse in der Komponente, somit ist es nicht notwendig, die URL zur Kommunikation zwischen JavaScript und Objective- C in der WebView zu setzen, sondern es genügt der Aufruf dieser URL in einem iFrame im Web Content.

Kommunikation über iFrame

Die Kommunikation auf diesem Weg erfolgt schneller als beim Aufruf über window.location.href und kommuniziert auch beim mehrmaligem Aufruf schnell hintereinander jedes Ereignis ins Objective-C, während bei der ersten Variante in diesem Fall nur ein Aufruf von vielen hintereinander im nativen Code ankommt.

Wurde das UIWebViewDelegate-Protokoll implementiert, wird dieses benachrichtigt, wenn eine neue Seite in der WebView geladen werden soll.

Neben „webViewDidStartLoad“ und „webViewDidFinishLoad“ die aufgerufen werden, wenn die neue Seite geladen wird oder fertig geladen ist, gibt es auch die Methode „webView:shouldStartLoadWithRequest:navigationType:“, die aufgerufen wird, bevor eine neue Seite in der WebView geladen wird. Diese ermöglicht es, die vorher zusammengesetzte URL, die anscheinend geladen werden soll, zuvor auf das selbst definierte Schlüsselwort zu prüfen und somit darauf zu reagieren.

Wird das Schlüsselwort gefunden, kann beispielsweise eine native Funktion aufgerufen werden. Der Rückgabewert NO sagt, dass diese URL nicht geladen werden soll. 
Handelt es sich hingegen wirklich um eine normale URL mit http:// beginnend, wird YES zurück gegeben und diese normal geladen.

Delegate Objective-C

Wird die native Funktion aufgerufen und soll diese wieder etwas zurück an die Browserkomponente liefern, kann eine Call-Back-Funktion definiert werden, welche aus dem nativen Teil aufgerufen wird.

JavaScript Call-Back-Funktion aufrufen:

JS Callback Funktion aufrufen

Dadurch ist es möglich, beliebiges JavaScript auszuführen, welches im NSString Objekt übergeben wird, und zum Beispiel eine Call-Back-Funktion aufzurufen und dieser im Parameter ein beliebiges Ergebnis mitzugeben. Allerdings darf das Script eine Laufzeit von 10 Sekunden nicht überschreiten, sonst wird es nicht weiter ausgeführt. Diese Limitierung wurde gemacht, um zu verhindern, dass die Ausführung eines Scripts den Main-Thread blockiert und der Benutzer nicht mehr mit der Website interagieren kann. Die Speicherallokierung ist ebenfalls auf 10 MB beschränkt und darf nicht überschritten werden, ansonsten wird eine Exception ausgelöst.

 

The comments are closed.