В этой статье я кратко расскажу, как взаимодействовать с (Angular) Javascript в WKWebView и Native Code. В основном это означает использование Javascript для вызова функции в собственном коде вашего приложения iOS (Swift) и наоборот.
Первым делом вы объявляете свой WKWebView:
var webView: WKWebView?
var request: NSURLRequest!
var url: NSURL!
//Then we add the WKWebViewConfiguration
var webConfig: WKWebViewConfiguration {
get {
let webCfg = WKWebViewConfiguration()
let userController = WKUserContentController()
let nativeCallHandler = NativeCallHandler()
nativeCallHandler.delegate = self
userController.addScriptMessageHandler(nativeCallHandler, name: "onNativeCalled")
webCfg.userContentController = userController;
return webCfg;
}
}
По сути, то, что мы сделали выше, заключалось в том, что в первую очередь я объявил WKWebView, а затем WKWebViewConfiguration, который представляет собой набор свойств, с помощью которых можно инициализировать веб-представление. Затем перейдем к нашему viewDidLoad
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
initViews()
}
func initViews() {
// The URL to load
url = NSURL(string: "http://sosososandso.com")
// Initialize our NSURLRequest
request = NSURLRequest(URL: url!)
// Set the frame of our WKWebView and add a configuration
webView = WKWebView(frame: self.view.frame, configuration: webConfig)
webView!.translatesAutoresizingMaskIntoConstraints = false
// Then we told our webview to load the request
webView!.loadRequest(request)
// Then we hooked it up to the webview navigation delegate. This is // not needed, just to debug the webview and know when the WKWebview // MessageHandler is
webView!.navigationDelegate = self
self.view.addSubview(webView!)
}
Итак, чтобы вызвать WKScriptMessageHandler, нам нужно создать класс NativeCallHandler и позволить ему создать подклассы NSObject и WKScriptMessageHandler. Затем мы переопределяем следующий метод
func userContentController(userContentController: WKUserContentController, didReceiveScriptMessage message: WKScriptMessage)
Глядя на все это должно быть так:
class NativeCallHandler: NSObject, WKScriptMessageHandler {
func userContentController(userContentController: WKUserContentController, didReceiveScriptMessage message: WKScriptMessage) {
if let messageBody: NSDictionary = message.body as? NSDictionary {
if let innerBody: NSDictionary = messageBody["body"] as? NSDictionary {
print(innerBody)
}
}
}
}
Выше мы просто сослались на ссылку на объект Dictionary и получили доступ к данным в нем.
По сути, это все, что вам нужно сделать, чтобы вызвать функцию, объявленную в вашем родном приложении iOS.
Что, если мы захотим вызвать функцию в нашем (Angular) коде Javascript?
На самом деле это очень просто:
webView?.evaluateJavaScript("callJSFunc('\(anyParameter requested by the JS function)')", completionHandler: nil)
NB: Пожалуйста, обратите внимание на функцию, названную выше. Перед «\» и после него стоит «‘ ». Если его не добавить, возникнет ошибка NSLocalizedDescription = Исключение JavaScript. Потому что вы неправильно ссылаетесь на функцию JS.
Итак, позвольте мне показать вам фрагмент кода Angular, вызывающего код собственного приложения.
$scope.$on('application', function(e, args){
var isMobile = {
Android: function() {
return navigator.userAgent.match(/Android/i);
},
BlackBerry: function() {
return navigator.userAgent.match(/BlackBerry/i);
},
iOS: function() {
return navigator.userAgent.match(/iPhone|iPad|iPod/i);
},
Opera: function() {
return navigator.userAgent.match(/Opera Mini/i);
},
Windows: function() {
return navigator.userAgent.match(/IEMobile/i);
},
any: function() {
return (isMobile.Android() || isMobile.BlackBerry() || isMobile.iOS() || isMobile.Opera() || isMobile.Windows());
}
};
if(isMobile.Android()){
window.verifiInterface.verifiID(parameterToPass);
//This is calling an android function
}
if(isMobile.iOS()){
var postObject = {
body: {
params: parameterToPass
}
};
window.webkit.messageHandlers.onNativeCalled.postMessage(postObject);
//This is passing message through WKWebView MessageHandler to the Native App
}
});
Но тогда, что, если мы хотим объявить нашу функцию для получения сообщения от приложения iOS.
window.callJSFunc = function(theParameter){
$scope.$apply(function(){
// Do whatever you want to do with data passed
});
};
И все. Возможно, в следующем посте я расскажу вам, как реализовать это для Android.