2016-09-08 3 views
6

Ich muss meinen Code zu swift 3 aktualisieren. Der Code unten ist die ursprüngliche Lösung, was perfekt funktioniert, aber in XCode 8 Beta und iOS 10 mit swift 3 der 'userContentController 'Delegat wird nicht aufgerufen, wenn ich den ursprünglichen html + js-Code verwende, um die native Seite aufzurufen.WKWebView WKScriptMessageHandler nicht mit iOS 10, XCode 8 beta aufgerufen

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

ich auch, keine Lösungen zu finden ... Hilfe! – Quadrivium

Antwort

1

Finden Sie den Weg, um es zu beheben? weil ich auch ein Problem habe, aber glücklicherweise konnte ich die Nachricht senden und userContentController hat zurückgerufen, aber nur Nachricht muss nur in der Nummer sein, keine Zeichenfolge, keine Zeichen. Ich weiß nicht warum ...

Bearbeitet Ich habe die Antwort darüber gefunden. Es ist offenbar, dass Sie in Try-Catch setzen haben und nachdem ich tat, dass es mit der Textnummer oder sogar json arbeitet 100% ist

`<script> 
    function callNative(message) { 
    try { 
     webkit.messageHandlers.callbackHandler.postMessage(message) 
    } catch(err) { 
     console.log("Error") 
    } 
    } 
</script>` 

Und vergessen Sie nicht, dass callbackHandler das gleiche Wort in der iOS sein muss, um Damit es funktioniert, müssen Sie nicht nennen Callbackhandler müssen, könnte man es etwas nennen, aber es hat die gleiche sein in sowohl Javascript und iOS

Hoffe, dass es Sie

+0

Ich habe auch Probleme mit WKScriptMessageHandler, die nicht auf iOS 10 aufgerufen werden. Ich habe das Problem in den Apple Entwicklerforen veröffentlicht: https://forums.developer.apple.com/message/180962 –

2

hilft ich dies nur fixiert, indem ein contentController mit wie

let contentController = WKUserContentController() 
contentController.add(self, name: "MyStuff") 

Dann analysiere ich in der UserContentController-Funktion den Körper, um die angeforderte Aktion und andere Parameter zu bestimmen. Wenn ich sende {Aktion: "DoThis", params: [1,2,3]}, würde mein Parsing-Code wie:

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 
    } 
} 
0

, was geschehen ist, weil im Grunde window.webkit.messageHandlers ein UserMessageHandlersNamespace Typ ist.

Sie sollten versuchen, ein Wörterbuch anstelle einer Zeichenfolge zu übergeben oder einem Array:

JavaScript Teil:

var dictionary = {"key1":"value1", "key2":"value2", "subDictionary": {"name": "foo"}} 
webkit.messageHandlers.refreshWebPage.postMessage(dictionary); 

Swift Teil:

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. (Dies funktioniert sowohl iOS9, iOS10 mit meinen Tests nach)

4

Afer ich eine Menge Zeit und Bedingungen debuggen, fand ich, dass:

  1. Die Funktion postMessage() in Ihrem JS muss eine haben Parameter, der Parameter nie

  2. der Parameter mussnull sein 210 Typ

  3. Zum Beispiel: webkit.messageHandlers.refreshWebPage.postMessage("status":"ok");

Wenn Sie die drei Ratschläge befolgt haben oben und haben die Delegierten richtig eingestellt. Die Delegiertenfunktion didReceiveScriptMessage wird aufgerufen. Hoffe das hilft dir.

Verwandte Themen