我需要将我的代码更新为swift 3.下面的代码是完美的原始解决方案,但在XCode 8 beta和iOS 10中使用swift 3的用户内容控制器'当我使用原始的html + js代码调用本机端时,委托不会调用。
class ViewController: UIViewController, WKUIDelegate, WKScriptMessageHandler, WKNavigationDelegate,UIWebViewDelegate,CLLocationManagerDelegate,URLSessionDataDelegate,UIImagePickerControllerDelegate, UINavigationControllerDelegate {
....
func initWebView(){
// JAVASCRIPT PART
let contentController = WKUserContentController();
let jScript:String = "var meta = document.createElement('meta'); meta.setAttribute('name', 'viewport'); meta.setAttribute('content', 'width=device-width'); document.getElementsByTagName('head')[0].appendChild(meta);";
let wkUScript:WKUserScript = WKUserScript(source: jScript, injectionTime: WKUserScriptInjectionTime.atDocumentEnd, forMainFrameOnly: true);
contentController.addUserScript(wkUScript)
contentController.add(
self,
name: "refreshWebPage"
)
contentController.add(
self,
name: "forceStepBack"
)
contentController.add(
self,
name: "setPageTitle"
)
contentController.add(
self,
name: "allowBackNavigate"
)
contentController.add(
self,
name: "changeBackNavigationURL"
)
contentController.add(
self,
name: "changeLeftButtonIconVisibility"
)
contentController.add(
self,
name: "changeRightButtonIconVisibility"
)
contentController.add(
self,
name: "clearWebCache"
)
contentController.add(
self,
name: "changeMobileAndPassword"
)
let config = WKWebViewConfiguration()
config.userContentController = contentController
self.webView = WKWebView(frame: CGRect.zero, configuration: config)
self.view.translatesAutoresizingMaskIntoConstraints = false
self.webView!.navigationDelegate = self
self.webView!.uiDelegate = self;
self.webView!.scrollView.bounces = false;
view = webView
webView?.loadHTMLString(self.baseURL!, baseURL: nil)
}
...
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
print("JavaScript is sending a message: \(message.body)")
print("JavaScript is sending a message.name: \(message.name)")
}
答案 0 :(得分:4)
我调试了很多时间和条件,我发现:
JS中的函数
postMessage()
必须有参数,参数永远不会为空参数必须为
JSON
类型- 醇>
例如:
webkit.messageHandlers.refreshWebPage.postMessage("status":"ok");
如果您已遵循上述三个建议并且委托设置正确。将调用委托函数didReceiveScriptMessage
。希望这能帮助你。
答案 1 :(得分:2)
我通过只有一个像
这样的contentController来解决这个问题let contentController = WKUserContentController()
contentController.add(self, name: "MyStuff")
然后在userContentController函数中我解析主体以确定请求的动作和其他参数。如果我发送{action:" doThis",params:[1,2,3]},我的解析代码就像:
if message.name == "MyStuff" {
let cmd:NSDictionary = message.body as! NSDictionary
let action:String = cmd["action"] as! String
switch action {
case "doThis":
// Do my stuff
break
default:
break
}
}
答案 2 :(得分:1)
您是否找到了修复方法?因为我也有问题但幸运的是,我可以发送消息并且userContentController确实回调了但是只有消息必须只有数字,没有字符串,没有字符。我不知道为什么......
<强>被修改强> 我找到了答案。 似乎你必须尝试捕获,在我这样做之后,它100%使用文本号甚至是json
`<script>
function callNative(message) {
try {
webkit.messageHandlers.callbackHandler.postMessage(message)
} catch(err) {
console.log("Error")
}
}
</script>`
并且不要忘记callbackHandler
必须与iOS中的同一个单词才能使其正常工作,您不必为callbackHandler命名,您可以将其命名为任何内容,但必须在Javascript和iOS中都是一样的
希望它可以帮到你
答案 3 :(得分:1)
发生这种情况是因为基本上window.webkit.messageHandlers
是UserMessageHandlersNamespace
类型。
您应该尝试传递字典而不是字符串或数组:
JavaScript部分:
var dictionary = {"key1":"value1", "key2":"value2", "subDictionary": {"name": "foo"}}
webkit.messageHandlers.refreshWebPage.postMessage(dictionary);
Swift部分:
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
let body = message.body
if let dict = body as? Dictionary<String, AnyObject> {
if let test = dict["key1"] {
print("JavaScript is sending a message \(value1)")
}
}
}
P.S。(根据我的测试,这适用于iOS9,iOS10)
答案 4 :(得分:0)
如果不是从JS使用webkit.messageHandlers.refreshWebPage
webkit.messageHandlers.refreshWebPage.postMessage("status":"ok")
然后您可以将其包装在WKUserContentController
上,如下所示,这样您就可以回叫
let userController = WKUserContentController()
let channelName = "postMessage"
let wrapperSource = "window.\(channelName) = webkit.messageHandlers.\(channelName);"
let wrapperScript = WKUserScript(
source: wrapperSource,
injectionTime: .atDocumentStart,
forMainFrameOnly: false)
userController.addUserScript(wrapperScript)
userController.add(self, name: "postMessage")
let configuration = WKWebViewConfiguration()
configuration.userContentController = userController
self.wkWebView = WKWebView(
frame: self.view.bounds,
configuration: configuration
)