В этой статье я кратко расскажу, как взаимодействовать с (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.