update with message handler string
This commit is contained in:
parent
bfe706908f
commit
83e04f0a12
@ -27,25 +27,19 @@ import WebKit
|
|||||||
|
|
||||||
override open func setupView() {
|
override open func setupView() {
|
||||||
super.setupView()
|
super.setupView()
|
||||||
let webView = createWebView(messageHandler: mvmWebViewMessageHandler, jsScript: nil)
|
let webView = createWebView(messageHandler: mvmWebViewMessageHandler)
|
||||||
addSubview(webView)
|
addSubview(webView)
|
||||||
NSLayoutConstraint.constraintPinSubview(toSuperview: webView)
|
NSLayoutConstraint.constraintPinSubview(toSuperview: webView)
|
||||||
self.webView = webView
|
self.webView = webView
|
||||||
pinSpinnerView()
|
pinSpinnerView()
|
||||||
}
|
}
|
||||||
|
|
||||||
func createWebView(messageHandler: String?, jsScript:String?) -> WKWebView {
|
func createWebView(messageHandler: String?) -> WKWebView {
|
||||||
let wkUserController = WKUserContentController()
|
let wkUserController = WKUserContentController()
|
||||||
if let messageHandlerName = messageHandler {
|
if let messageHandlerName = messageHandler {
|
||||||
wkUserController.add(self, name: messageHandlerName)
|
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()
|
let wkConfig = WKWebViewConfiguration()
|
||||||
wkConfig.userContentController = wkUserController
|
wkConfig.userContentController = wkUserController
|
||||||
let webView = WKWebView(frame: .zero, configuration: wkConfig)
|
let webView = WKWebView(frame: .zero, configuration: wkConfig)
|
||||||
@ -59,33 +53,29 @@ import WebKit
|
|||||||
// MARK: - MVMCoreUIMoleculeViewProtocol
|
// MARK: - MVMCoreUIMoleculeViewProtocol
|
||||||
override open func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) {
|
override open func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) {
|
||||||
super.set(with: model, delegateObject, additionalData)
|
super.set(with: model, delegateObject, additionalData)
|
||||||
guard let model = model as? WebViewModel else { return }
|
|
||||||
self.delegateObject = delegateObject
|
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
|
//init height for loading spinner
|
||||||
webViewHeight = webView?.heightAnchor.constraint(equalToConstant: 50)
|
webViewHeight = webView?.heightAnchor.constraint(equalToConstant: 44)
|
||||||
webViewHeight?.isActive = true
|
webViewHeight?.isActive = true
|
||||||
|
|
||||||
if let height = model.height {
|
if let height = webviewModel?.height {
|
||||||
webViewHeight?.constant = height
|
webViewHeight?.constant = height
|
||||||
dynamicHeight = false
|
dynamicHeight = false
|
||||||
}
|
}
|
||||||
if let url = model.url {
|
if let url = webviewModel?.url {
|
||||||
webView?.load(URLRequest(url: url))
|
webView?.load(URLRequest(url: url))
|
||||||
} else if let htmlString = model.htmlString {
|
} else if let htmlString = webviewModel?.htmlString {
|
||||||
webView?.loadHTMLString(htmlString, baseURL: nil)
|
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)
|
bringSubviewToFront(loadingSpinner)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,8 +85,8 @@ import WebKit
|
|||||||
loadingSpinner.clipsToBounds = true
|
loadingSpinner.clipsToBounds = true
|
||||||
loadingSpinner.translatesAutoresizingMaskIntoConstraints = false
|
loadingSpinner.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
|
||||||
loadingSpinner.heightAnchor.constraint(equalToConstant: 50.0).isActive = true
|
loadingSpinner.heightAnchor.constraint(equalToConstant: 44.0).isActive = true
|
||||||
loadingSpinner.widthAnchor.constraint(equalToConstant: 50.0).isActive = true
|
loadingSpinner.widthAnchor.constraint(equalToConstant: 44.0).isActive = true
|
||||||
loadingSpinner.centerXAnchor.constraint(equalTo: centerXAnchor).isActive = true
|
loadingSpinner.centerXAnchor.constraint(equalTo: centerXAnchor).isActive = true
|
||||||
loadingSpinner.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true
|
loadingSpinner.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true
|
||||||
loadingSpinner.resumeSpinner()
|
loadingSpinner.resumeSpinner()
|
||||||
@ -114,7 +104,6 @@ extension WebView : WKUIDelegate {
|
|||||||
if !dynamicHeight {
|
if !dynamicHeight {
|
||||||
return
|
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".
|
/* 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
|
so webView.isLoading to check load finished state
|
||||||
*/
|
*/
|
||||||
@ -157,14 +146,20 @@ extension WebView : WKNavigationDelegate {
|
|||||||
// MARK: - WKScriptMessageHandler
|
// MARK: - WKScriptMessageHandler
|
||||||
extension WebView: WKScriptMessageHandler {
|
extension WebView: WKScriptMessageHandler {
|
||||||
public func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
|
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);
|
receiving JavaScript func webkit.messageHandlers.{callHandler}.postMessage(body);
|
||||||
if body is dictionary
|
if body is string, will decode to actionmodel.
|
||||||
MVMCoreActionHanlder handleAction
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,8 +15,7 @@ import Foundation
|
|||||||
public var url: URL?
|
public var url: URL?
|
||||||
public var htmlString: String?
|
public var htmlString: String?
|
||||||
public var height: CGFloat?
|
public var height: CGFloat?
|
||||||
public var jsScript: String?
|
public var borderColor: Color?
|
||||||
public var callHandler: String?
|
|
||||||
public var buttonMap: [String: ButtonModel]?
|
public var buttonMap: [String: ButtonModel]?
|
||||||
|
|
||||||
private enum CodingKeys: String, CodingKey{
|
private enum CodingKeys: String, CodingKey{
|
||||||
@ -26,8 +25,7 @@ import Foundation
|
|||||||
case htmlString
|
case htmlString
|
||||||
case height
|
case height
|
||||||
case buttonMap
|
case buttonMap
|
||||||
case jsScript
|
case borderColor
|
||||||
case callHandler
|
|
||||||
}
|
}
|
||||||
|
|
||||||
required public init(from decoder: Decoder) throws {
|
required public init(from decoder: Decoder) throws {
|
||||||
@ -37,8 +35,7 @@ import Foundation
|
|||||||
htmlString = try typeContainer.decodeIfPresent(String.self, forKey: .htmlString)
|
htmlString = try typeContainer.decodeIfPresent(String.self, forKey: .htmlString)
|
||||||
height = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .height)
|
height = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .height)
|
||||||
buttonMap = try typeContainer.decodeIfPresent([String: ButtonModel].self, forKey: .buttonMap)
|
buttonMap = try typeContainer.decodeIfPresent([String: ButtonModel].self, forKey: .buttonMap)
|
||||||
jsScript = try typeContainer.decodeIfPresent(String.self, forKey: .jsScript)
|
borderColor = try typeContainer.decodeIfPresent(Color.self, forKey: .borderColor)
|
||||||
callHandler = try typeContainer.decodeIfPresent(String.self, forKey: .callHandler)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public func encode(to encoder: Encoder) throws {
|
public func encode(to encoder: Encoder) throws {
|
||||||
@ -48,8 +45,6 @@ import Foundation
|
|||||||
try container.encodeIfPresent(url, forKey: .url)
|
try container.encodeIfPresent(url, forKey: .url)
|
||||||
try container.encodeIfPresent(htmlString, forKey: .htmlString)
|
try container.encodeIfPresent(htmlString, forKey: .htmlString)
|
||||||
try container.encodeIfPresent(height, forKey: .height)
|
try container.encodeIfPresent(height, forKey: .height)
|
||||||
try container.encodeIfPresent(jsScript, forKey: .jsScript)
|
try container.encodeIfPresent(borderColor, forKey: .borderColor)
|
||||||
try container.encodeIfPresent(callHandler, forKey: .callHandler)
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user