diff --git a/MVMCoreUI/Atomic/Atoms/Views/WebView.swift b/MVMCoreUI/Atomic/Atoms/Views/WebView.swift index c5cc0cf9..3d870f53 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/WebView.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/WebView.swift @@ -27,25 +27,19 @@ import WebKit override open func setupView() { super.setupView() - let webView = createWebView(messageHandler: mvmWebViewMessageHandler, jsScript: nil) + let webView = createWebView(messageHandler: mvmWebViewMessageHandler) addSubview(webView) NSLayoutConstraint.constraintPinSubview(toSuperview: webView) self.webView = webView pinSpinnerView() } - func createWebView(messageHandler: String?, jsScript:String?) -> WKWebView { + func createWebView(messageHandler: String?) -> WKWebView { let wkUserController = WKUserContentController() if let messageHandlerName = messageHandler { wkUserController.add(self, name: messageHandlerName) } - //server driven addition script - if let jsScript = jsScript { - let wkScript = WKUserScript(source: jsScript, injectionTime: .atDocumentStart, forMainFrameOnly: true) - wkUserController.addUserScript(wkScript) - } - let wkConfig = WKWebViewConfiguration() wkConfig.userContentController = wkUserController let webView = WKWebView(frame: .zero, configuration: wkConfig) @@ -59,33 +53,29 @@ import WebKit // MARK: - MVMCoreUIMoleculeViewProtocol override open func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { super.set(with: model, delegateObject, additionalData) - guard let model = model as? WebViewModel else { return } self.delegateObject = delegateObject - - if model.callHandler != nil || model.jsScript != nil { -/* - webView's configuration property is immutable. - In order to add call handler into webview, need to create a new webview. -*/ - webView?.removeFromSuperview() - let webView = createWebView(messageHandler: model.callHandler, jsScript:model.jsScript) - addSubview(webView) - NSLayoutConstraint.constraintPinSubview(toSuperview: webView) - self.webView = webView - } //init height for loading spinner - webViewHeight = webView?.heightAnchor.constraint(equalToConstant: 50) + webViewHeight = webView?.heightAnchor.constraint(equalToConstant: 44) webViewHeight?.isActive = true - if let height = model.height { + if let height = webviewModel?.height { webViewHeight?.constant = height dynamicHeight = false } - if let url = model.url { + if let url = webviewModel?.url { webView?.load(URLRequest(url: url)) - } else if let htmlString = model.htmlString { + } else if let htmlString = webviewModel?.htmlString { webView?.loadHTMLString(htmlString, baseURL: nil) } + + if let borderColor = webviewModel?.borderColor?.cgColor { + webView?.layer.borderWidth = 1.0 + webView?.layer.borderColor = borderColor + } else { + webView?.layer.borderWidth = 0.0 + webView?.layer.borderColor = UIColor.clear.cgColor + } + bringSubviewToFront(loadingSpinner) } @@ -95,8 +85,8 @@ import WebKit loadingSpinner.clipsToBounds = true loadingSpinner.translatesAutoresizingMaskIntoConstraints = false - loadingSpinner.heightAnchor.constraint(equalToConstant: 50.0).isActive = true - loadingSpinner.widthAnchor.constraint(equalToConstant: 50.0).isActive = true + loadingSpinner.heightAnchor.constraint(equalToConstant: 44.0).isActive = true + loadingSpinner.widthAnchor.constraint(equalToConstant: 44.0).isActive = true loadingSpinner.centerXAnchor.constraint(equalTo: centerXAnchor).isActive = true loadingSpinner.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true loadingSpinner.resumeSpinner() @@ -114,7 +104,6 @@ extension WebView : WKUIDelegate { if !dynamicHeight { return } - /* was using "document.readyState" to check the state, while evaluateJavaScript "document.readyState",only works when webview contains userscrpt.otherwise, it would return WKErrorDomain Code=4 "A JavaScript exception occurred". so webView.isLoading to check load finished state */ @@ -157,14 +146,20 @@ extension WebView : WKNavigationDelegate { // MARK: - WKScriptMessageHandler extension WebView: WKScriptMessageHandler { public func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) { - if message.name == mvmWebViewMessageHandler, let actionMap = message.body as? [AnyHashable: Any] { + if message.name == mvmWebViewMessageHandler, let text = message.body as? String { /* receiving JavaScript func webkit.messageHandlers.{callHandler}.postMessage(body); - if body is dictionary - MVMCoreActionHanlder handleAction + if body is string, will decode to actionmodel. + use legacy MVMCoreActionHanlder handleAction method for now */ - MVMCoreActionHandler.shared()?.handleAction(with: actionMap, additionalData: nil, delegateObject: self.delegateObject) - + if let data = text.data(using: .utf8) { + do { + let actionMap = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] + MVMCoreActionHandler.shared()?.handleAction(with: actionMap, additionalData: nil, delegateObject: self.delegateObject) + } catch { + //actionModel should report error when actionhandler is finshed with actionmodel + } + } } } } diff --git a/MVMCoreUI/Atomic/Atoms/Views/WebViewModel.swift b/MVMCoreUI/Atomic/Atoms/Views/WebViewModel.swift index bb141b57..d20a5007 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/WebViewModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/WebViewModel.swift @@ -15,8 +15,7 @@ import Foundation public var url: URL? public var htmlString: String? public var height: CGFloat? - public var jsScript: String? - public var callHandler: String? + public var borderColor: Color? public var buttonMap: [String: ButtonModel]? private enum CodingKeys: String, CodingKey{ @@ -26,8 +25,7 @@ import Foundation case htmlString case height case buttonMap - case jsScript - case callHandler + case borderColor } required public init(from decoder: Decoder) throws { @@ -37,8 +35,7 @@ import Foundation htmlString = try typeContainer.decodeIfPresent(String.self, forKey: .htmlString) height = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .height) buttonMap = try typeContainer.decodeIfPresent([String: ButtonModel].self, forKey: .buttonMap) - jsScript = try typeContainer.decodeIfPresent(String.self, forKey: .jsScript) - callHandler = try typeContainer.decodeIfPresent(String.self, forKey: .callHandler) + borderColor = try typeContainer.decodeIfPresent(Color.self, forKey: .borderColor) } public func encode(to encoder: Encoder) throws { @@ -48,8 +45,6 @@ import Foundation try container.encodeIfPresent(url, forKey: .url) try container.encodeIfPresent(htmlString, forKey: .htmlString) try container.encodeIfPresent(height, forKey: .height) - try container.encodeIfPresent(jsScript, forKey: .jsScript) - try container.encodeIfPresent(callHandler, forKey: .callHandler) - + try container.encodeIfPresent(borderColor, forKey: .borderColor) } }