Swift実践ブログ

ド文系アラサー社会人が独学でプログラミングを学ぶ記録

【Swift】WKWebViewで進む/戻る/更新(リロード)機能を実装する

■はじめに

スワイプで進む/戻る/更新(リロード)機能を実装してみたのでまとめます。

 

■開発環境

Xcode 9.4.1

・Swift 4.1.2

 

■進む/戻る機能の実装

インスタンスプロパティ「allowsBackForwardNavigationGestures」で、スワイプで進む/戻る機能を有効にできます。

// スワイプで進む、戻るを有効にする
webView.allowsBackForwardNavigationGestures = true

 

■更新(リロード)機能の実装

bouncesを有効にし、UIRefreshControlをインスタンス化。更新に関するメソッドのイベントを受け取るよう下記のように実装します。

self.webView.scrollView.bounces = true
let refreshControl = UIRefreshControl()
self.webView.scrollView.refreshControl = refreshControl
refreshControl.addTarget(self, action: #selector(ViewController.refreshWebView(sender:)), for: .valueChanged)

 

更新に関するメソッドは以下。

@objc func refreshWebView(sender: UIRefreshControl) {
        webView.reload()
        sender.endRefreshing()
}

 

■サンプル

import UIKit
import WebKit

class ViewController: UIViewController {
    
    var webView: WKWebView!
    
    // Viewを作成する
    override func loadView() {
        
        super.loadView()
        let viewConfiguration = WKWebViewConfiguration()
        webView = WKWebView(frame: .zero, configuration: viewConfiguration)
        self.view = webView
        
        webView.uiDelegate = self
        webView.navigationDelegate = self
        
        // スワイプで戻る、進むを有効にする
        webView.allowsBackForwardNavigationGestures = true
        
        // リロードのイベントを受け取る
        self.webView.scrollView.bounces = true
        let refreshControl = UIRefreshControl()
        self.webView.scrollView.refreshControl = refreshControl
        refreshControl.addTarget(self, action: #selector(ViewController.refreshWebView(sender:)), for: .valueChanged)
    }
    
    // Webページを読み込む
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // 表示するWebページのURLRequestを作る
        let myURL = URL(string: "{表示したいURL}")
        let myRequest = URLRequest(url: myURL!)
        
        // Webページを読み込む
        webView.load(myRequest)
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    
    // ページをリロードするメソッド
    @objc func refreshWebView(sender: UIRefreshControl) {
        webView.reload()
        sender.endRefreshing()
    }
}

// target=”_blank”が設定されたリンク先を開けるようにする
extension ViewController: WKUIDelegate {
    func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? {
        if navigationAction.targetFrame == nil {
            webView.load(navigationAction.request)
        }
        return nil
    }
}

 

■おわりに

スワイプで更新する機能に関しては実装方法がいくつかネット上で紹介されていますが、うまくいかない方の参考になればと思います。 

 

■関連リンク

allowsBackForwardNavigationGestures - WKWebView | Apple Developer Documentation

bounces - UIScrollView | Apple Developer Documentation

UIRefreshControl - UIKit | Apple Developer Documentation

 ・[iOS 10] 全てのスクロールビューでRefresh Controlがサポートされました | Developers.IO

【Swift】WKWebViewでリンク先が開けない場合の対処法(ATS/target=”_blank”)

■はじめに

【Swift】WKWebViewでhttpsのページを表示できない原因(ATS) - Swift実践ブログでは、httpsのページに遷移できない現象について取り上げましたが、今回はリンク先が開けない現象に関してまとめたいと思います。

 

■開発環境

Xcode 9.4.1

・Swift 4.1.2

 

■現象

リンク先をタップしても開けない(画面が白くなるわけでもなく、全く反応しない)

※該当ページはSafariの場合、リンク先をタップすると新しいタブにリンク先が表示される。

 

■検証

1.ATS設定が怪しい

AllowsArbitraryLoadsをYESに変更してもリンク先は開けない。

 

2.「target=”_blank”」が怪しい

以下記事から、開けないリンクのソースを確認したところ「target=”_blank”」が見事に設定されていました。しかし、「target=”_blank”」が設定されたリンクでも、必ずしも新しいタブが開くとは限らず、タブが開かないリンクは遷移できる状況でした。また、記事に掲載されている実装方法を参考にしても解決できず。

[iOS] WKWebView で target=”_blank” のリンクを開く方法 | Developers.IO

WKWebViewでtarget="_blank"なリンクが開かない時の対処法

 

■解決

新しいWebビューを作成するインスタンスメソッド「webView(_:createWebViewWith:for:windowFeatures:)」を使うことは検証2と同じものの、以下記事に掲載されている実装方法を参考にして解決しました。

【Swift4】WKWebViewのミニマムサンプル【iOS】

 

■実装部分

import UIKit
import WebKit

class ViewController: UIViewController {
    
    var webView: WKWebView!
    
   // Viewを作成する
    override func loadView() {
        super.loadView()
        let viewConfiguration = WKWebViewConfiguration()
        webView = WKWebView(frame: .zero, configuration: viewConfiguration)
  self.view = webView
        webView.uiDelegate = self
    }
    
   // Webページを読み込む
    override func viewDidLoad() {
        super.viewDidLoad()
        let myURL = URL(string: "{表示したいURL}")
        let myRequest = URLRequest(url: myURL!)
        webView.load(myRequest)
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}

// (Safariでは新しいタブがひらく)リンク先を開けるようにする
extension ViewController: WKUIDelegate {
    func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? {
        if navigationAction.targetFrame == nil {
            webView.load(navigationAction.request)
        }
        return nil
    }
}

  

■おわりに

リンク先をタップしても何も反応がない状況から、原因を特定して実装し解決するまでかなり時間がかかってしまいました。表題のテーマでは多くの記事がありますが、本記事が少しでも参考になればと思います。

 

■関連リンク

WKWebView - WebKit | Apple Developer Documentation

[iOS] WKWebView で target=”_blank” のリンクを開く方法 | Developers.IO

WKWebViewでtarget="_blank"なリンクが開かない時の対処法

webView(_:createWebViewWith:for:windowFeatures:) - WKUIDelegate | Apple Developer Documentation

【Swift4】WKWebViewのミニマムサンプル【iOS】

【Swift】WKWebViewでhttpsのページを表示できない原因(ATS)

■はじめに

WKWebViewでhttpsのページを表示できずはまってしまった時に調べたことのまとめ。

 

■開発環境

Xcode 9.4.1

・Swift 4.1.2

 

■ 現象

httpのページを表示するにはATSの設定が必要ですが、一部httpsのページなのに表示できないもの(画面が真っ白になって表示されないもの)があることに気づきました。念のためATSのException Domainの設定をしてみたのですが、結果は変わらず。

 

■原因

該当のURLをnscurlのコマンドで確認したところ、サーバーへの安全な接続を確立できないとメッセージがでました。リダイレクト関連の通信でhttpがあるとATSによって弾かれてしまうようですね。

※参考:

WkWebviewで外部のWebサイトに繋がらないときにチェックすること

iOS - WKWebViewでリダイレクトされた時にページに遷移しない(60437)|teratail

  

リダイレクト先を確認する方法に関しては以下記事で紹介されています。

※参考:swift(ver2.2)でリダイレクト先のURLを取得する

 

■対応

リダイレクト先もException Domainの設定に含めるか、非推奨ですがAllowsArbitraryLoadsをYESにして無効化すると表示できるようになります。

 

■おわりに

 ATSは設定によっては申請時にリジェクトされるリスクがある箇所かと思うので、より調べてみます。

 

追記(2018/8/29)

リンク先をタップしても何も反応しない現象に関しては以下記事にまとめました。

【Swift】WKWebViewでリンク先が開けない場合の対処法(ATS/target=”_blank”) - Swift実践ブログ

 

■関連リンク

WKWebView - WebKit | Apple Developer Documentation

Security - Apple Developer

WkWebviewで外部のWebサイトに繋がらないときにチェックすること

iOS - WKWebViewでリダイレクトされた時にページに遷移しない(60437)|teratail

swift(ver2.2)でリダイレクト先のURLを取得する