Вы не можете. Как упоминалось в @Clement, вы можете использовать обещания и вызывать функцию разрешения. Неплохой (хотя и с использованием Deferred, который сейчас считается антишаблоном) пример GoldenGate.
В Javascript вы можете создать объект двумя способами: отправить и разрешить: (я скомпилировал cs в js для облегчения чтения)
this.Goldengate = (function() {
function Goldengate() {}
Goldengate._messageCount = 0;
Goldengate._callbackDeferreds = {};
Goldengate.dispatch = function(plugin, method, args) {
var callbackID, d, message;
callbackID = this._messageCount;
message = {
plugin: plugin,
method: method,
"arguments": args,
callbackID: callbackID
};
window.webkit.messageHandlers.goldengate.postMessage(message);
this._messageCount++;
d = new Deferred;
this._callbackDeferreds[callbackID] = d;
return d.promise;
};
Goldengate.callBack = function(callbackID, isSuccess, valueOrReason) {
var d;
d = this._callbackDeferreds[callbackID];
if (isSuccess) {
d.resolve(valueOrReason[0]);
} else {
d.reject(valueOrReason[0]);
}
return delete this._callbackDeferreds[callbackID];
};
return Goldengate;
})();
Затем вы звоните
Goldengate.dispatch("ReadLater", "makeSomethingHappen", []);
И со стороны iOS:
func userContentController(userContentController: WKUserContentController, didReceiveScriptMessage message: WKScriptMessage) {
let message = message.body as! NSDictionary
let plugin = message["plugin"] as! String
let method = message["method"] as! String
let args = transformArguments(message["arguments"] as! [AnyObject])
let callbackID = message["callbackID"] as! Int
println("Received message #\(callbackID) to dispatch \(plugin).\(method)(\(args))")
run(plugin, method, args, callbackID: callbackID)
}
func transformArguments(args: [AnyObject]) -> [AnyObject!] {
return args.map { arg in
if arg is NSNull {
return nil
} else {
return arg
}
}
}
func run(plugin: String, _ method: String, _ args: [AnyObject!], callbackID: Int) {
if let result = bridge.run(plugin, method, args) {
println(result)
switch result {
case .None: break
case .Value(let value):
callBack(callbackID, success: true, reasonOrValue: value)
case .Promise(let promise):
promise.onResolved = { value in
self.callBack(callbackID, success: true, reasonOrValue: value)
println("Promise has resolved with value: \(value)")
}
promise.onRejected = { reason in
self.callBack(callbackID, success: false, reasonOrValue: reason)
println("Promise was rejected with reason: \(reason)")
}
}
} else {
println("Error: No such plugin or method")
}
}
private func callBack(callbackID: Int, success: Bool, reasonOrValue: AnyObject!) {
// we're wrapping reason/value in array, because NSJSONSerialization won't serialize scalar values. to be fixed.
bridge.vc.webView.evaluateJavaScript("Goldengate.callBack(\(callbackID), \(success), \(Goldengate.toJSON([reasonOrValue])))", completionHandler: nil)
}
Обратите внимание на эту замечательную статью о обещаниях.
person
Karol Klepacki
schedule
27.05.2015
UIWebviewDelegate
методы; и с нативного на javascript через методstringByEvaluatingJavaScriptFromString
. Вы также можете создать свой собственный мост. - person atulkhatri   schedule 26.03.2015