ios WKWebViewでWebViewアプリの作り方まとめとく

iOSで簡単なWebViewアプリの作るときに必要そうなことまとめておく。以下のiOS
android WebViewアプリの作り方まとめとく - とりあえずphpとか

WKWebViewを作ってサイトを表示する

ViewController

import UIKit
import WebKit

class ViewController: UIViewController {

    var webView: WKWebView!

    override func viewDidLoad() {
        super.viewDidLoad()

        webView = WKWebView(frame: CGRect(x: 0, y: 0, width: view.frame.width, height: view.frame.height))
        view.addSubview(webView)

        let request = URLRequest(url: URL(string: "https://www.google.com")!)
        webView.load(request)
    }
}

クッキーの値を取得する

takuyaokamoto.hateblo.jp

スワイプでブラウザバック

webView.allowsBackForwardNavigationGestures = true

メールや電話の起動リンクに対応

class ViewController: UIViewController, WKNavigationDelegate {
    ・・・
    override func viewDidLoad() {
       ・・・
        webView.navigationDelegate = self
       ・・・
    }

    func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {

        guard let url = navigationAction.request.url else {
            return
        }

        if navigationAction.navigationType == .linkActivated {
            if url.scheme == "mailto" || url.scheme == "tel" {
                UIApplication.shared.open(url, options: [:], completionHandler: nil)
                decisionHandler(.cancel)
                return
            }
        }

        decisionHandler(.allow)
    }
}

SSLエラーやhttpとhttpsの混在ページを読み込む

info.plist

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

ViewController

class ViewController: UIViewController, WKNavigationDelegate {
    ・・・
    func webView(_ webView: WKWebView, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Swift.Void) {
        if challenge.protectionSpace.host == "example.com" && challenge.protectionSpace.serverTrust != nil {
            let credential = URLCredential(trust: challenge.protectionSpace.serverTrust!)
            completionHandler(.useCredential, credential)
        } else {
            completionHandler(.performDefaultHandling, nil)
        }
    }
}

Pull To Refreshを実装する

class ViewController: UIViewController, WKNavigationDelegate {

    var webView: WKWebView!
    var refreshControll: UIRefreshControl!

    override func viewDidLoad() {
        ・・・
        refreshControll = UIRefreshControl()
        self.webView.scrollView.refreshControl = refreshControll
        refreshControll.addTarget(self, action: #selector(ViewController.refresh(sender:)), for: .valueChanged)
        ・・・
    }


    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        self.refreshControll.endRefreshing()
    }

    @objc func refresh(sender: UIRefreshControl) {
        guard let url = webView.url else {
            return
        }
        webView.load(URLRequest(url: url))
    }
}

他のサイトは表示したくない

class ViewController: UIViewController, WKNavigationDelegate {
    ・・・
    func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
        ・・・
        if url.host != "example.com" {
            decisionHandler(.cancel)
            return
        }

        decisionHandler(.allow)
    }
}

全ソース

import UIKit
import WebKit

class ViewController: UIViewController, WKNavigationDelegate {

    var webView: WKWebView!
    var refreshControll: UIRefreshControl!

    override func viewDidLoad() {
        super.viewDidLoad()

        webView = WKWebView(frame: CGRect(x: 0, y: 0, width: view.frame.width, height: view.frame.height))
        webView.navigationDelegate = self
        webView.allowsBackForwardNavigationGestures = true
        refreshControll = UIRefreshControl()
        self.webView.scrollView.refreshControl = refreshControll
        refreshControll.addTarget(self, action: #selector(ViewController.refresh(sender:)), for: .valueChanged)
        view.addSubview(webView)

        let url = "https://example.com"
        let request = URLRequest(url: URL(string: url)!)
        webView.load(request)
    }

    func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {

        guard let url = navigationAction.request.url else {
            return
        }

        if navigationAction.navigationType == .linkActivated {
            if url.scheme == "mailto" || url.scheme == "tel" {
                UIApplication.shared.open(url, options: [:], completionHandler: nil)
                decisionHandler(.cancel)
                return
            }
        }

        if url.host != "example.com" {
            decisionHandler(.cancel)
            return
        }

        decisionHandler(.allow)
    }

    func webView(_ webView: WKWebView, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Swift.Void) {
        if challenge.protectionSpace.host == "example.com" && challenge.protectionSpace.serverTrust != nil {
            let credential = URLCredential(trust: challenge.protectionSpace.serverTrust!)
            completionHandler(.useCredential, credential)
        } else {
            completionHandler(.performDefaultHandling, nil)
        }
    }

    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        self.refreshControll.endRefreshing()
    }

    @objc func refresh(sender: UIRefreshControl) {
        guard let url = webView.url else {
            return
        }
        webView.load(URLRequest(url: url))
    }
}

androidiosもそこそこ手間でした、、以上です