2016-09-08 14 views
6

私のコードをswift 3に更新する必要があります。以下のコードは、完全に動作する元のソリューションですが、XCode 8ベータ版とiOS 10のswift 3では 'userContentController元のhtml + jsコードを使用してネイティブ側を呼び出すと、デリゲートが呼び出されません。WKWebView WKScriptMessageHandlerがiOS 10、XCode 8ベータで呼び出されていない

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はへのiOSで同じ単語なければならないことを忘れないでください、あなたがたcallbackHandlerに名前を付ける必要はありません、それを動作させる、あなたはそれを任意の名前を付けることができますが、それは

が、それは私が一つだけcontentControllerを持つことによって、これを固定あなた

+0

また、iOS 10でWKScriptMessageHandlerが呼び出されないという問題も発生します.Apple Developer Forums:https://forums.developer.apple.com/message/180962で問題を投稿しました。 –

2

を役に立てば幸いJavascriptとiOSの両方で同じである必要がありますlike

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

次に、userContentController関数で、ボディを解析して、要求されたアクションと他のパラメータを決定します。私は{: "doThis"、のparams:アクション[1,2,3]}送信する場合:基本的にwindow.webkit.messageHandlersUserMessageHandlersNamespaceタイプですので起こった

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

、私の解析コードは次のようになります。

代わりに、文字列または配列の辞書を渡すようにしてください:

JavaScriptの一部:

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

スウィフト一部:

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、私はことを発見:

あなたのJSで
  1. 機能postMessage()が持っている必要がありますパラメータパラメータパラメータでなければなりません

  2. nullになることはありませんJSON種類例えば

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

  4. あなたは上記の3つのアドバイスに従っていると、デリゲートは、正しい設定している場合

。デリゲート関数didReceiveScriptMessageが呼び出されます。これがあなたのお役に立てば幸いです。

関連する問題