詳細
- Xcode 9.1、スウィフト 4
- Xcode 10.2 (10E125)、スウィフト 5
説明
スクリプトは、WKWebView に表示されるページに挿入されます。このスクリプトはページの URL を返します (ただし、別の JavaScript コードを記述できます)。これは、スクリプト イベントが Web ページで生成されることを意味しますが、関数で処理されます。
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {...}
解決
extension WKUserScript {
enum Defined: String {
case getUrlAtDocumentStartScript = "GetUrlAtDocumentStart"
case getUrlAtDocumentEndScript = "GetUrlAtDocumentEnd"
var name: String { return rawValue }
private var injectionTime: WKUserScriptInjectionTime {
switch self {
case .getUrlAtDocumentStartScript: return .atDocumentStart
case .getUrlAtDocumentEndScript: return .atDocumentEnd
}
}
private var forMainFrameOnly: Bool {
switch self {
case .getUrlAtDocumentStartScript: return false
case .getUrlAtDocumentEndScript: return false
}
}
private var source: String {
switch self {
case .getUrlAtDocumentEndScript, .getUrlAtDocumentStartScript:
return "webkit.messageHandlers.\(name).postMessage(document.URL)"
}
}
fileprivate func create() -> WKUserScript {
return WKUserScript(source: source,
injectionTime: injectionTime,
forMainFrameOnly: forMainFrameOnly)
}
}
}
extension WKWebViewConfiguration {
func add(script: WKUserScript.Defined, scriptMessageHandler: WKScriptMessageHandler) {
userContentController.addUserScript(script.create())
userContentController.add(scriptMessageHandler, name: script.name)
}
}
使用法
WKWebView の初期化
let config = WKWebViewConfiguration()
config.add(script: .getUrlAtDocumentStartScript, scriptMessageHandler: self)
config.add(script: .getUrlAtDocumentEndScript, scriptMessageHandler: self)
webView = WKWebView(frame: UIScreen.main.bounds, configuration: config)
webView.navigationDelegate = self
view.addSubview(webView)
イベントをキャッチ
extension ViewController: WKScriptMessageHandler {
func userContentController (_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
if let script = WKUserScript.Defined(rawValue: message.name),
let url = message.webView?.url {
switch script {
case .getUrlAtDocumentStartScript: print("start: \(url)")
case .getUrlAtDocumentEndScript: print("end: \(url)")
}
}
}
}
完全なコード例
import UIKit
import WebKit
class ViewController: UIViewController, WKNavigationDelegate {
private var webView = WKWebView()
override func viewDidLoad() {
super.viewDidLoad()
let config = WKWebViewConfiguration()
config.add(script: .getUrlAtDocumentStartScript, scriptMessageHandler: self)
config.add(script: .getUrlAtDocumentEndScript, scriptMessageHandler: self)
webView = WKWebView(frame: UIScreen.main.bounds, configuration: config)
webView.navigationDelegate = self
view.addSubview(webView)
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
webView.load(urlString: "http://apple.com")
}
}
extension ViewController: WKScriptMessageHandler {
func userContentController (_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
if let script = WKUserScript.Defined(rawValue: message.name),
let url = message.webView?.url {
switch script {
case .getUrlAtDocumentStartScript: print("start: \(url)")
case .getUrlAtDocumentEndScript: print("end: \(url)")
}
}
}
}
extension WKWebView {
func load(urlString: String) {
if let url = URL(string: urlString) {
load(URLRequest(url: url))
}
}
}
extension WKUserScript {
enum Defined: String {
case getUrlAtDocumentStartScript = "GetUrlAtDocumentStart"
case getUrlAtDocumentEndScript = "GetUrlAtDocumentEnd"
var name: String { return rawValue }
private var injectionTime: WKUserScriptInjectionTime {
switch self {
case .getUrlAtDocumentStartScript: return .atDocumentStart
case .getUrlAtDocumentEndScript: return .atDocumentEnd
}
}
private var forMainFrameOnly: Bool {
switch self {
case .getUrlAtDocumentStartScript: return false
case .getUrlAtDocumentEndScript: return false
}
}
private var source: String {
switch self {
case .getUrlAtDocumentEndScript, .getUrlAtDocumentStartScript:
return "webkit.messageHandlers.\(name).postMessage(document.URL)"
}
}
fileprivate func create() -> WKUserScript {
return WKUserScript(source: source,
injectionTime: injectionTime,
forMainFrameOnly: forMainFrameOnly)
}
}
}
extension WKWebViewConfiguration {
func add(script: WKUserScript.Defined, scriptMessageHandler: WKScriptMessageHandler) {
userContentController.addUserScript(script.create())
userContentController.add(scriptMessageHandler, name: script.name)
}
}
Info.plist
Info.plist トランスポート セキュリティ設定を追加します
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
結果

資力
Document オブジェクトのプロパティとメソッド