2017-04-02 21 views
2

を返さないがevaluateJavaScriptでWKWebView負荷()から返されたが、それは何も印刷されません。私はこの権利をしていますか?他の方法? didFinishは印刷します。WKWebView evaluateJavaScriptがHTML

import UIKit 
import WebKit 

class MyWebViewController: UIViewController, WKNavigationDelegate { 

var webView: WKWebView! 

override func viewDidLoad() { 
    super.viewDidLoad() 

    webView = WKWebView(frame: self.view.frame) 
    webView.navigationDelegate = self 

    let url = NSURL (string: "https://google.com"); 
    let request = NSURLRequest(url: url! as URL) 
    webView.load(request as URLRequest) 

    self.view.addSubview(webView) 

    self.view.sendSubview(toBack: webView) 

} 


func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { 

    webView.evaluateJavaScript("document.documentElement.outerHTML.toString()", completionHandler: { (html: AnyObject?, error: NSError?) in 
     print(html!) 
     } as? (Any?, Error?) -> Void) 

    print("didFinish") 

} 

} WKWebViewevaluateJavaScriptを使用

答えて

2

は少しトリッキーです。

私はこの回答が多くの人々に役立つと思うので、具体的な質問に短いコードスニペットと、WKScriptMessageHandlerを実装する必要があるコメントを記述するのではなく、完全な完全な例を投稿しますすべてが一緒にどのように動作するかを確認するために使用することができます。

これを使用するには、Xcodeで「シングルビューアプリケーション」のiOSプロジェクトを作成し、デフォルト ViewController.swiftファイルの上にこれを貼り付けます。

// 
// WebViewController.swift 
// WKWebViewExample 
// 
// Created by par on 4/2/17. 
// Copyright © 2017 par. All rights reserved. MIT License. 
// 

import UIKit 
import WebKit 

class ViewController: UIViewController { 
    override func viewDidLoad() { 
     super.viewDidLoad() 

     let webViewController = WebViewController() 

     // install the WebViewController as a child view controller 
     addChildViewController(webViewController) 

     let webViewControllerView = webViewController.view! 

     view.addSubview(webViewControllerView) 

     webViewControllerView.translatesAutoresizingMaskIntoConstraints = false 
     webViewControllerView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true 
     webViewControllerView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true 
     webViewControllerView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true 
     webViewControllerView.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true 

     webViewController.didMove(toParentViewController: self) 
    } 
} 

class WebViewController: UIViewController, WKNavigationDelegate, WKScriptMessageHandler { 
    private var webView: WKWebView! 
    private var webViewContentIsLoaded = false 

    init() { 
     super.init(nibName: nil, bundle: nil) 

     self.webView = { 
      let contentController = WKUserContentController() 

      contentController.add(self, name: "WebViewControllerMessageHandler") 

      let configuration = WKWebViewConfiguration() 
      configuration.userContentController = contentController 

      let webView = WKWebView(frame: .zero, configuration: configuration) 
      webView.scrollView.bounces = false 
      webView.navigationDelegate = self 

      return webView 
     }() 
    } 

    required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     view.addSubview(webView) 

     webView.translatesAutoresizingMaskIntoConstraints = false 
     webView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true 
     webView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true 
     webView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true 
     webView.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true 
    } 

    override func viewWillAppear(_ animated: Bool) { 
     super.viewWillAppear(animated) 

     if !webViewContentIsLoaded { 
      let url = URL(string: "https://google.com")! 
      let request = URLRequest(url: url) 

      webView.load(request) 

      webViewContentIsLoaded = true 
     } 
    } 

    private func evaluateJavascript(_ javascript: String, sourceURL: String? = nil, completion: ((_ error: String?) -> Void)? = nil) { 
     var javascript = javascript 

     // Adding a sourceURL comment makes the javascript source visible when debugging the simulator via Safari in Mac OS 
     if let sourceURL = sourceURL { 
      javascript = "//# sourceURL=\(sourceURL).js\n" + javascript 
     } 

     webView.evaluateJavaScript(javascript) { _, error in 
      completion?(error?.localizedDescription) 
     } 
    } 

    // MARK: - WKNavigationDelegate 

    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { 
     // This must be valid javascript! Critically don't forget to terminate statements with either a newline or semicolon! 
     let javascript = 
      "var outerHTML = document.documentElement.outerHTML.toString()\n" + 
      "var message = {\"type\": \"outerHTML\", \"outerHTML\": outerHTML }\n" + 
      "window.webkit.messageHandlers.WebViewControllerMessageHandler.postMessage(message)\n" 

     evaluateJavascript(javascript, sourceURL: "getOuterHMTL") 
    } 

    // MARK: - WKScriptMessageHandler 

    func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) { 
     guard let body = message.body as? [String: Any] else { 
      print("could not convert message body to dictionary: \(message.body)") 
      return 
     } 

     guard let type = body["type"] as? String else { 
      print("could not convert body[\"type\"] to string: \(body)") 
      return 
     } 

     switch type { 
     case "outerHTML": 
      guard let outerHTML = body["outerHTML"] as? String else { 
       print("could not convert body[\"outerHTML\"] to string: \(body)") 
       return 
      } 
      print("outerHTML is \(outerHTML)") 
     default: 
      print("unknown message type \(type)") 
      return 
     } 
    } 
} 
関連する問題