質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

1回答

7950閲覧

WKWebViewのエラーハンドリングについて知りたい

sunglass

総合スコア303

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2020/10/06 06:20

WKWebViewを使用してwebページを表示しています。

画面は2つあります。

dataにURLの文字列が渡されるとそのwebページが開く仕様です。
URLの文字列は(前の)画面遷移から渡される仕組みです。
前の画面では httpsかどうかをチェックしていますが、ページのURLが正しいかどうかはチェックしていません。

参考にした記事:https://qiita.com/haru15komekome/items/894ddaa33e1d7aabfe26

【聞きたいこと】 ・ページのURLが正しいかどうかを判断するのは遷移前の画面でしょうか。 それとも(遷移後の)webページを開く画面で判断するのでしょうか。 ・(もし後者であれば)webページを開く際に正しくないURLが渡された場合のエラーハンドリング方法を知りたいです。

※簡単なものでも良いです。
webで言う404みたいに存在しないwebページの場合はこちらで用意したhttps:hogehoge.com/404みたいのに飛ばしたいです。

import WebKit class WebViewController: UIViewController, WKNavigationDelegate, UINavigationControllerDelegate { var webView: WKWebView! var data: String = "" @IBOutlet weak var webPage: WKWebView! ... override func viewDidLoad() { super.viewDidLoad() let homeUrl = self.data openUrl(urlString: homeUrl) webPage.navigationDelegate = self } // 文字列で指定されたURLをWeb Viewを開く func openUrl(urlString: String) { let url = URL(string: urlString) let request = NSURLRequest(url: url!) webPage.load(request as URLRequest) } extension ViewController: WKNavigationDelegate { // WebView読み込み時エラー func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) { print("読み込みに失敗しました。") self.navigationController?.popViewController(animated: true) } }

イメージ説明

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

・ページのURLが正しいかどうかを判断するのは遷移前の画面でしょうか。

それとも(遷移後の)webページを開く画面で判断するのでしょうか。

それは、sunglassさんが考えられているインタフェースデザイン次第かと思います。

遷移前の画面でURLが正しいか否かを判断し、画面遷移せず「不正なURLです」とエラーを出すのも一つですし、とりあえず遷移させたあと、あらかじめ準備したページを表示する方法もあるかと思います。

これについては、どちらが正解かは状況次第ですので、sunglassさんで要件を詰めていただければと思います。

・(もし後者であれば)webページを開く際に正しくないURLが渡された場合のエラーハンドリング方法を知りたいです。

delegate の一つである

Swift

1func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void)

で、表示したいページが 404 か否かを判断することはできるのですが、404だった場合に違うページに飛ばそうとするとなかなか厄介でうまくいきません(別の方だとすんなりできるかもしれません)。

そもそも、サーバのレスポンスを得るのであれば、URLSessionで指定したページにアクセスし、レスポンスを得て判断した方が見通しが効くコードになるかもしれません。

たとえば、func openUrl(urlString:) を次のように書き換えていただくと、URL として正しくない、あるいは 404 なページを表示しようとした場合には、あらかじめ設定しておいたページを表示するようにできます。

Swift

1 func openUrl(urlString: String) { 2 var url = URL(string: urlString) 3 4 // エラー発生時にリダイレクトする URL 5 let redirectURL = URL(string: "https://teratail.com") 6 7 // 一度 url に接続し、レスポンスを確認する 8 URLSession.shared.dataTask(with: url!) { _, response, error in 9 // ネットワークエラーが発生した場合 10 if let error = error as? URLError { 11 if error.code == .unsupportedURL { 12 // URL の形式が正しくなかった場合 13 url = redirectURL 14 } else { 15 // URLError 型には色々な種類があるので、もっと検討する余地はある 16 print(error.localizedDescription) 17 return 18 } 19 } 20 21 // とりあえずサーバに接続できた場合 22 if let httpResponse = response as? HTTPURLResponse { 23 switch httpResponse.statusCode { 24 case 404: 25 //case 400..<500: 26 // 当然、ほかの400系エラーについても考慮する必要がある。 27 // 400系のエラーは全て一括りにして良いのであれば、400..<500 でまとめる 28 29 // url はリダイレクト先にする 30 url = redirectURL 31 default: 32 // それ以外の場合は何もしない 33 break 34 } 35 } 36 37 // WkWebView はメインキューで操作する必要がある。 38 DispatchQueue.main.async { 39 let request = URLRequest(url: url!) 40 self.webPage.load(request) 41 } 42 }.resume() 43 }

サーバにアクセスするにしても、

  • URL そのものが正しくない
  • クライアントサイドの問題である(400系エラー)
  • サーバサイドの問題である(500系エラー)
  • その他

などなど、考えなければならない選択肢は多岐に渡るかと思いますが、実装方針としては上記のような方法があるのではないでしょうか。

ちなみに、上記のコードでレスポンスを取得する部分だけを実装すれば、遷移前画面でアクセス可能な URL か否かを判断することは可能かと思います。

投稿2020/10/06 13:45

編集2020/10/06 14:10
TsukubaDepot

総合スコア5086

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sunglass

2020/10/06 14:07 編集

めちゃくちゃ丁寧な解説ありがとうございます。。 早速実装してみます。
TsukubaDepot

2020/10/06 14:12

例によって思いつきですが、openUrl をクロージャを取るメソッドで実装すれば、もう少し応用の幅は広がるかもしれまん。
sunglass

2020/10/06 14:16

そちらも検討してみます!  ただクロージャじゃなくても書いてもらったコードの可読性も応用性も高そうなので.. まずは回答してもらったらコードで実装してみます! (WKWebView 癖あってキャッシュ削除も面倒そうです。。悩ましいです。。)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問