Skip to content

Instantly share code, notes, and snippets.

@KentarouKanno
Last active March 30, 2023 17:24
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save KentarouKanno/09aef71aa34e5828641778d303abf9d8 to your computer and use it in GitHub Desktop.
Save KentarouKanno/09aef71aa34e5828641778d303abf9d8 to your computer and use it in GitHub Desktop.
WKWebView

WKWebView

import UIKit
import WebKit

class ViewController: UIViewController, WKNavigationDelegate {
    
    var wkWebView: WKWebView!
    let observerKeyName = ["estimatedProgress", "loading", "title", "URL", "hasOnlySecureContent", "canGoBack", "canGoForward"]
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        wkWebView = WKWebView()
        wkWebView.navigationDelegate = self
        view = wkWebView
        
        addObserver()
        
        // スワイプで戻るを許可
        wkWebView.allowsBackForwardNavigationGestures = true
        
        if let url = URL(string:"https://gist.github.com/KentarouKanno/27d260c6d834f290266d") {
            let req = NSURLRequest(url:url)
            wkWebView.load(req as URLRequest)
        }
    }
    
    // MARK: --- Observer ---
    
    deinit {
        removeOvserver()
    }
    
    func addObserver() {
        observerKeyName.forEach{ wkWebView.addObserver(self, forKeyPath: $0, options: .new, context: nil)}
    }
    
    func removeOvserver() {
        observerKeyName.forEach{ wkWebView.removeObserver(self, forKeyPath: $0) }
    }
    
    // プロパティ監視
    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey: Any]?, context: UnsafeMutableRawPointer?) {
        
        if let keyPath = keyPath {
            switch keyPath {
            case "estimatedProgress":
                
                if let change = change, let progress = change[NSKeyValueChangeKey.newKey] as? Float {
                    if(progress < 1.0) {
                        
                        // プログレスバーを更新する
                        print("loading :\(progress)")
                        
                        UIApplication.shared.isNetworkActivityIndicatorVisible = true
                    } else {
                        
                        print("loaded : Finish")
                        UIApplication.shared.isNetworkActivityIndicatorVisible = false
                    }
                }
                
            case "loading"    :
                print("observe --- loading")
                if let change = change, let loading = change[NSKeyValueChangeKey.newKey] as? NSNumber {
                    print(loading) // 0 => loading終了, 1 => loading開始
                }
                
            case "title"      :
                print("observe --- title")
                if let change = change, let title = change[NSKeyValueChangeKey.newKey] as? String {
                    self.title = title
                }
            case "URL"        :
                print("observe --- URL")
                if let change = change, let url = change[NSKeyValueChangeKey.newKey] as? NSURL {
                    print(url)
                }
            case "hasOnlySecureContent": print("observe --- hasOnlySecureContent")
            case "canGoBack"  :
                print("observe --- canGoBack")
                if let change = change, let canGoBack = change[NSKeyValueChangeKey.newKey] as? NSNumber {
                    print(canGoBack) // 0 => Back不可 , 1 => Back可能
                }
                
            case "canGoForward":
                print("observe --- canGoForward")
                if let change = change, let canGoForward = change[NSKeyValueChangeKey.newKey] as? NSNumber {
                    print(canGoForward) // 0 => Forward不可 , 1 => Forward可能
                }
                
            default: break
            }
        }
    }
    
    // MARK: --- WKNavigationDelegate ---
    
    func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
        // ページ読み込みが開始された時
        print("didStartProvisionalNavigation")
    }
    
    func webView(_ webView: WKWebView, didCommit navigation: WKNavigation!) {
        // 遷移開始時
        print("didCommitNavigation")
    }
    
    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        // title = webView.title
        // ページ読み込みが完了した時
        print("didFinishNavigation")
    }
    
    func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
        // 遷移中にエラーが発生した時
        print("didFailNavigation")
    }
    
    func webView(_ webView: WKWebView, didReceiveServerRedirectForProvisionalNavigation navigation: WKNavigation!) {
        // リダイレクトされた時
        print("didReceiveServerRedirectForProvisionalNavigation")
    }
    
    func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) {
        // ページ読み込み時にエラーが発生した時
        print("didFailProvisionalNavigation")
    }
    
    
    func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
        // Webサイトにリクエストを送る前に判断する
        decisionHandler(.allow)  // .Allow or .Cancel
        
        // ※.Cancelにすると処理がここで終了
        
        print("request ---", navigationAction.request)                       // 遷移先に関してのNSURLRequestオブジェクト
        // print(navigationAction.sourceFrame)                               // 遷移元に関してのWKFrameInfoオブジェクト
        print("targetFrame ---",navigationAction.targetFrame ?? "")                // 遷移先に関してのWKFrameInfoオブジェクト
        print("navigationType ---",navigationAction.navigationType.rawValue) // 遷移の種類を示すenum値
        
        /*
         case LinkActivated   = 0 : aタグによる遷移
         case FormSubmitted   = 1 : フォームの送信による遷移
         case BackForward     = 2 : 進む、戻るによる遷移
         case Reload          = 3 : 更新による遷移
         case FormResubmitted = 4 : フォームの再送信による遷移
         case Other           = 5 : その他の方法による遷移
         */
        
        print("decidePolicyForNavigationAction")
    }
    
    func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) {
        // Webサイトからレスポンスが帰ってきた後に判断する
        decisionHandler(.allow)  // .Allow or .Cancel
        
        // ※.CancelにするとdidFailProvisionalNavigationが呼ばれる
        
        print("response ---", navigationResponse.response)               // 遷移先に関してのNSURLResponseオブジェクト
        print("forMainFrame ---", navigationResponse.isForMainFrame)       // 遷移がmainFrameで行われるかを示すbool値?
        print("canShowMIMEType ---", navigationResponse.canShowMIMEType) // 遷移先のMIMETypeが表示可能かどうかを示すbool値
        
        print("decidePolicyForNavigationResponse")
    }
    
    /*
     func webView(webView: WKWebView, didReceiveAuthenticationChallenge challenge: NSURLAuthenticationChallenge, completionHandler: (NSURLSessionAuthChallengeDisposition, NSURLCredential?) -> Void) {
     print("didReceiveAuthenticationChallenge")
     }
     */
}

★ iOS9 ATS

<key>NSAppTransportSecurity</key>
    <dict>
        <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>

★ blankページが開けない場合の対応その1

import UIKit
import WebKit

class ViewController: UIViewController, WKNavigationDelegate, WKUIDelegate {

    var wkWebView: WKWebView!

    override func viewDidLoad() {
        super.viewDidLoad()

        wkWebView = WKWebView()
        wkWebView.navigationDelegate = self
        wkWebView.uiDelegate = self

        view = wkWebView

        // スワイプで戻るを許可
        wkWebView.allowsBackForwardNavigationGestures = true

        if let url = URL(string:"http://game.granbluefantasy.jp/#authentication") {
            let req = NSURLRequest(url:url)
            wkWebView.load(req as URLRequest)
        }
    }

    func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? {
        guard let url = navigationAction.request.url else {
            return nil
        }

        guard let targetFrame = navigationAction.targetFrame, targetFrame.isMainFrame else {
            webView.load(URLRequest(url: url))
            return nil
        }
        return nil
    }
}

★ blankページが開けない場合の対応その2

WKUIDelegate

wkWebView.uiDelegate = self

func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? {
    guard let url = navigationAction.request.url else {
        return nil
    }

    guard let targetFrame = navigationAction.targetFrame, targetFrame.isMainFrame else {
        webView.load(URLRequest(url: url))
        return nil
    }
    return nil
}

★ Create folder referenceで追加したhtmlを取得して表示する

import UIKit
import WebKit

class ViewController: UIViewController, WKNavigationDelegate, WKUIDelegate {

    
    var wkWebView: WKWebView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        wkWebView = WKWebView()
        wkWebView.navigationDelegate = self
        wkWebView.uiDelegate = self
        
        view = wkWebView
    
        let path  = Bundle.main.url(forResource: "html/lisence/lisence", withExtension: "html")
        wkWebView.load(URLRequest(url: path!))
    }
}

s

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment