I've converted the example in to Swift but there doesn't appear to be any communication between swift and js at all.. Is there something I am doing wrong? - There are no errors reported.
I am loading the html content from a localhost url instead of including the html file, apart from that I don't think I've done anything different, here is my Swift file. (I did test including the html file in the project instead but I still did not see any communication)
import Foundation
import WebViewJavascriptBridge
class IntroWebView:UIViewController, UIWebViewDelegate {
var bridge:WebViewJavascriptBridge!
override func viewDidAppear(animated: Bool) {
if let _ = self.bridge { return }
let webView = UIWebView(frame: self.view.frame)
self.view.addSubview(webView)
WebViewJavascriptBridge.enableLogging()
self.bridge = WebViewJavascriptBridge(forWebView: webView)
self.bridge.setWebViewDelegate(self)
self.bridge.registerHandler("testObjcCallback", handler: { (data:AnyObject!, responseCallback:WVJBResponseCallback!) in
print("testObjcCallback called: \(data)")
responseCallback("Response from testObjcCallback")
})
self.bridge.callHandler("testJavascriptHandler", data: ["foo","before ready"])
renderButtons(webView)
self.loadExamplePage(webView)
}
func webViewDidStartLoad(webView: UIWebView) {
print("webViewDidStartLoad")
}
func webViewDidFinishLoad(webView: UIWebView) {
print("webViewDidFinishLoad")
}
func renderButtons(webView:UIWebView) {
let font = UIFont(name:"HelveticaNeue", size:11)
let callbackButton = UIButton(frame: CGRect(x: 0, y: 400, width: 100, height: 35))
callbackButton.setTitle("Call handler", forState: .Normal)
callbackButton.addTarget(self, action: #selector(IntroWebView.callHandler(_:)), forControlEvents: .TouchUpInside)
callbackButton.titleLabel?.font = font
callbackButton.backgroundColor = UIColor.darkGrayColor()
self.view.addSubview(callbackButton)
let reloadButton = UIButton(frame: CGRect(x: 90, y: 400, width: 100, height: 35))
reloadButton.setTitle("Reload webview", forState: .Normal)
reloadButton.addTarget(webView, action: #selector(webView.reload), forControlEvents: .TouchUpInside)
reloadButton.titleLabel?.font = font
reloadButton.backgroundColor = UIColor.darkGrayColor()
self.view.addSubview(reloadButton)
}
func callHandler(sender:UIButton) {
let data = ["greetingFromObjC": "Hi there, JS!"]
print(data)
self.bridge.callHandler("testJavascriptHandler", data: data, responseCallback: { (response:AnyObject!) in
print("response \(data)")
})
}
func loadExamplePage(webView:UIWebView) {
let url = "http://localhost:8888"
let request = NSURLRequest(URL: NSURL(string:url)!)
webView.loadRequest(request)
}
}
And the html is an exact copy of the example code here:
<!doctype html>
<html><head>
<meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1.0, maximum-scale=1.0">
<style type='text/css'>
html { font-family:Helvetica; color:#222; }
h1 { color:steelblue; font-size:24px; margin-top:24px; }
button { margin:0 3px 10px; font-size:12px; }
.logLine { border-bottom:1px solid #ccc; padding:4px 2px; font-family:courier; font-size:11px; }
</style>
</head><body>
<h1>WebViewJavascriptBridge Demo</h1>
<script>
window.onerror = function(err) {
log('window.onerror: ' + err)
}
function setupWebViewJavascriptBridge(callback) {
if (window.WebViewJavascriptBridge) { return callback(WebViewJavascriptBridge); }
if (window.WVJBCallbacks) { return window.WVJBCallbacks.push(callback); }
window.WVJBCallbacks = [callback];
var WVJBIframe = document.createElement('iframe');
WVJBIframe.style.display = 'none';
WVJBIframe.src = 'https://__bridge_loaded__';
document.documentElement.appendChild(WVJBIframe);
setTimeout(function() { document.documentElement.removeChild(WVJBIframe) }, 0)
}
setupWebViewJavascriptBridge(function(bridge) {
var uniqueId = 1
function log(message, data) {
var log = document.getElementById('log')
var el = document.createElement('div')
el.className = 'logLine'
el.innerHTML = uniqueId++ + '. ' + message + ':<br/>' + JSON.stringify(data)
if (log.children.length) { log.insertBefore(el, log.children[0]) }
else { log.appendChild(el) }
}
bridge.registerHandler('testJavascriptHandler', function(data, responseCallback) {
log('ObjC called testJavascriptHandler with', data)
var responseData = { 'Javascript Says':'Right back atcha!' }
log('JS responding with', responseData)
responseCallback(responseData)
})
document.body.appendChild(document.createElement('br'))
var callbackButton = document.getElementById('buttons').appendChild(document.createElement('button'))
callbackButton.innerHTML = 'Fire testObjcCallback'
callbackButton.onclick = function(e) {
e.preventDefault()
log('JS calling handler "testObjcCallback"')
bridge.callHandler('testObjcCallback', {'foo': 'bar'}, function(response) {
log('JS got response', response)
})
}
})
</script>
<div id='buttons'></div> <div id='log'></div>
</body></html>
Here is a screenshot.

I've converted the example in to Swift but there doesn't appear to be any communication between swift and js at all.. Is there something I am doing wrong? - There are no errors reported.
I am loading the html content from a localhost url instead of including the html file, apart from that I don't think I've done anything different, here is my Swift file. (I did test including the html file in the project instead but I still did not see any communication)
And the html is an exact copy of the example code here:
Here is a screenshot.