2016-09-08 2 views
6

Мне нужно обновить мой код до быстрого 3. Код ниже - это оригинальное решение, которое отлично работает, но в XCode 8 beta и iOS 10 с быстрым 3 «userContentController» 'делегат не вызывается, когда я использую оригинальный код html + js для вызова собственной стороны.WKWebView WKScriptMessageHandler не вызывается с iOS 10, XCode 8 beta

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

меня тоже, не найдя никаких решений ... ПОМОЩЬ! – Quadrivium

ответ

1

Вы нашли способ исправить это? потому что у меня есть проблема, но, к счастью, я мог отправить сообщение, а userContentController вызвал обратно, но только сообщение должно быть только в номере, ни строки, ни символов. Я не знаю, почему ...

Отредактировано Я узнал ответ об этом. Это, кажется, что вы должны поставить в попытке поймать и после того, как я сделал, что это 100% работает с номером текста или даже JSON

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

И не забывайте, что callbackHandler должно быть то же самое слово в ИСН заставить его работать, вы не должны называть CallbackHandler, вы могли бы назвать это ничего, но он должен быть таким же как в JavaScript, и прошивке

Надеется, что это помогает вам

+0

У меня также возникают проблемы с WKScriptMessageHandler, которые не вызывают на iOS 10. Я опубликовал эту проблему на форумах разработчиков Apple: https://forums.developer.apple.com/message/180962 –

2

Я исправил это, только имея один contentController подобные

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

Затем в функции userContentController проанализируйте тело, чтобы определить запрошенное действие и другие параметры. Если я посылаю {действие: "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 
    } 
} 
0

Это произошло потому, что в основном 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

Afer отладить много времени и условий, я обнаружил, что:

  1. Функция postMessage() в ваших JS должны иметь параметр, параметрникогда не будет нулевой

  2. параметр должен быть JSON Тип

  3. Например: webkit.messageHandlers.refreshWebPage.postMessage("status":"ok");

Если вы следовали три советы выше и делегат установить правильно. Будет вызываться функция делегата didReceiveScriptMessage. Надеюсь, это поможет вам.

Смежные вопросы