Gdg dev fest hybrid apps your own mini-cordova

Post on 27-Jan-2017

33 views 3 download

Transcript of Gdg dev fest hybrid apps your own mini-cordova

Hybrid Apps and Qortoba: Your own mini-Cordova

Ayman MahfouzVP of Engineering @ Webalo

December 2016

Agenda

- Bio- Problem Context- Introducing Hybrid Apps- Native-to-JS communication- Project Qortoba- Q&A

Problem Context - Webalo Platform

www.webalo.com

Native Apps

Pros

● Performance● Security● Familiarity● Access to Device

Cons

● Portability● Maintenance● Time to Market

So?

Native Apps - Shared Code

Shared Java code allows for extensibility, but how to open the Webalo Client up for third party extension?

Solution - Hybrid App

Java / Obj-C

WebViewHTML + JS

?

The Matrix!

Native to JavaScript

Android

Java to JavaScript

API

void evaluateJavascript(String script, ValueCallback<String> resultCallback)

webView.evaluateJavascript(“someJavaScriptFunction();”, new ValueCallback<String>() {

public void onReceiveValue(String s) { JsonReader reader = new JsonReader(new StringReader(s));

JsonToken token = JsonReader.peek() ... }});

Usage

Java to JavaScript - Notes

Requirements

1. API level 19.2. WebSettings.setJavaScriptEnabled(true) // false by default3. Must be called on UI thread.

evaluateJavascript(...)

Properties

1. Asynchronous evaluation.2. Context of currently displayed page.3. Callback made on UI thread.4. Callback value is a JSON object. To pass String values use

JsonReader.setLenient(true).

Java to JavaScript - Pre 19

void loadUrl(String url)

Usage

webView.loadUrl(“javascript:someJsFunction();”);

API

Pitfall - Navigate away

webView.loadUrl(“javascript:someJsFunction();void(0);”);

No return value!

[INFO:CONSOLE(1)] "Uncaught SyntaxError: Unexpected token ILLEGAL", source: (1)

Common error

Native to JavaScript

iOS

Objective-C to JavaScript

WKWebView API (iOS 8+)

- (void)evaluateJavaScript : (NSString *)javaScriptString completionHandler : (void (^)(id, NSError *error))completionHandler;

[webView evaluateJavaScript : script completionHandler:^(id result, NSError *error) { if (error == nil) { if (result != nil) { NSString* resultString = [NSString stringWithFormat:@"%@", result]; ... } } else { NSLog(@"evaluateJavaScript error : %@", error.localizedDescription); } }];

Usage

Objective-C to JavaScript - Pre iOS 8

UIWebView API

- (NSString *)stringByEvaluatingJavaScriptFromString : (NSString *)script;

NSString *title = [webView stringByEvaluatingJavaScriptFromString:@"document.title"];

NSString *ten = [webView stringByEvaluatingJavaScriptFromString:@"var x = 2; x * 5;"];

Usage

Objective-C to JavaScript - Notes

- (void) viewDidLoad {

// Send page load request to Web View

}

- (void) webViewDidFinishLoad : (UIWebView *)webView {

// Ask Web View to evaluate JavaScript

}

Back to the Matrix!

JavaScript to Native

Android

JavaScript to Java

Inject objects into the displayed page context:

private final class Api {

public void showMessage(String message) { Log.d(TAG, message); }}webView.addJavascriptInterface(new Api(), "MyJavaObj");

Starting API 17

void addJavascriptInterface(Object serviceApi, String name)

Usage

API

MyJavaObj.showMessage(“Hello There!”);

Java

JS

@JavascriptInterface

JavaScript to Java - Notes

1. Injected objects will not appear in JavaScript until the page is next (re)loaded.

webView.loadData("", "text/html", null);

2. WebView interacts with Java object on a background thread. 3. Serialization of arguments

a. Simple types and stringsb. Serialize objects as JSON

4. Use WebChromeClient to handle callbacks

webView.setWebChromeClient(new WebChromeClient() { public boolean onJsAlert(...) { // display alert in OS theme } }); }

Troubleshooting

Use Chrome “Inspect” feature

chrome://inspectMust enable debugging

WebView.setWebContentsDebuggingEnabled(true);

android.view.ViewRootImpl$CalledFromWrongThreadException[INFO:CONSOLE(13)] "Uncaught ReferenceError: MyJavaObj is not defined"

1. Run calls from JavaScript on UI Thread. 2. Invoked too early

a. Wait till page loads WebViewClient.onPageFinished()b. May need call to force page load using

webView.loadData("", "text/html", null);

Debugging

Common Causes

Common Errors

JavaScript to Native

iOS

JavaScript to Objective-C

Inject an object into WK

@interface MyHandler : NSObject<WKScriptMessageHandler> { … }

- (void)userContentController : (WKUserContentController *)userContentController didReceiveScriptMessage: (WKScriptMessage *)message { NSDictionary *dict = (NSDictionary*)message.body; NSString *str = [dict objectForKey:@"strField"]; NSNumber *num = [dict objectForKey:@"numField"]; ...}

[webView.configuration.userContentController addScriptMessageHandler : myHandlerObject

name : @"handlerNameInJs"];

Usage

API

window.webkit.messageHandlers.handlerNameInJs.postMessage( { ‘strField’ : “Some string value”, ‘numField’ : 3 } );

Obj

ectiv

e-C

JS

JavaScript to Objective-C - Pre iOS 8

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest : (NSURLRequest *)request navigationType : (UIWebViewNavigationType)navigationType {

NSURL* url = request.URL;

if ( ! [url.scheme isEqualToString:@"myapp"]) { return YES; }

// decode the invocation

NSString* methodName = [hostStrEncoded stringByRemovingPercentEncoding]; NSString* queryStr = [[url query] stringByRemovingPercentEncoding]; ... return NO;}

Usage - UIWebViewDelegate

Point the browser to the function you want to invoke!API

document.location.href = “myapp://methodName?param1=test&param2=3

Obj

ectiv

e-C

JS

The Matrix Reloaded!

Project Qortoba

Cordova (Qortoba) - Spain

Features

● Utilities for JavaScript-to-Native communications.● Unified OS-version-independent interface.● Strongly-typed Java interfaces proxying JavaScript.● Hide UIWebView delegate implementation.● Scripts for generating JavaScript classes.● Communication with AngularJS services.

Project Qortoba

github.com/amahfouz/qortoba

Extensions

● Callbacks for JavaScript-to-Native.● Handling object graphs.● Object parameter serialization.● More code generation scripts.● Better error handling.● Platforms other than Android and iOS.

Project Qortoba

github.com/amahfouz/qortoba