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

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

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

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Xcode

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

Swift

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

Q&A

解決済

1回答

1042閲覧

WebkitでTwitterを開くと400 Bad Requestが出る。

sunglass

総合スコア303

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Xcode

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

Swift

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

0グッド

0クリップ

投稿2020/12/25 15:14

今まで問題なく下記のコードで TwitterのURLを開くことが出来ていたのですが急に 404のエラーを返すようになりました。

TwitterのURLは https://twitter.com/TwitterJPなどで余計な文字列は付与していません。
iOS13と14ともに同じ症状が出ます。

https://www.yahoo.co.jp/https://www.youtube.com/とかは普通に見れます。

Twitterの方で何か処理が変わったのでしょうか。。
Webkitで Twitterを正常に開きたいです。
それとも TwitterのURLは弾くしかないのでしょうか。。

import UIKit import WebKit class WebViewController: UIViewController, WKNavigationDelegate, UINavigationControllerDelegate, GADBannerViewDelegate var webView: WKWebView! var data: String = "" @IBOutlet weak var backButton: UIBarButtonItem! @IBOutlet weak var forwardButton: UIBarButtonItem! var toolbarHeight:CGFloat = 0 @IBOutlet weak var webPage: WKWebView! override func viewDidLoad() { super.viewDidLoad() webPage.navigationDelegate = self self.toolbarHeight = navigationController?.toolbar.frame.size.height as! CGFloat navigationController?.delegate = self self.navigationController?.setNavigationBarHidden(false, animated: true) self.navigationController?.navigationBar.isHidden = false self.navigationController?.isNavigationBarHidden = false let homeUrl = self.data openUrl(urlString: homeUrl) webPage.navigationDelegate = self } override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) self.navigationController?.setNavigationBarHidden(true, animated: true) self.navigationController?.navigationBar.isHidden = true self.navigationController?.isNavigationBarHidden = true } func openUrl(urlString: String) { var url = URL(string: urlString) // エラー用URL let redirectURL = URL(string: "https://test.com") URLSession.shared.dataTask(with: url!) { _, response, error in if let error = error as? URLError { if error.code == .unsupportedURL { url = redirectURL print("失敗①") } else { print(error.localizedDescription) return } } if let httpResponse = response as? HTTPURLResponse { switch httpResponse.statusCode { case 300..<399: print("失敗②") case 400: url = redirectURL print("400 Bad Requestです。") case 403: url = redirectURL print("403 Forbiddenです。") case 404: url = redirectURL print("404 Not Foundです。") case 408: url = redirectURL print("408 Request Timeoutです。") case 409..<500: url = redirectURL print("このエラーは409 -500系のものです。") default: break } } DispatchQueue.main.async { let request = URLRequest(url: url!) self.webPage.load(request) } }.resume() } func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) { backButton.isEnabled = false forwardButton.isEnabled = false } func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { backButton.isEnabled = webView.canGoBack forwardButton.isEnabled = webView.canGoForward } @IBAction func backButton(_ sender: Any) { webPage.goBack() } @IBAction func forwardButton(_ sender: Any) { webPage.goForward() } }

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

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

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

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

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

guest

回答1

0

ベストアンサー

dataTask(with:) を使って接続可能か否かを判断されていますが、これは正しい方法ではないと思います。

Web系の詳細はわかりませんが、URLSession を使うのであれば、user agent などを正しく設定しない場合、サーバがエラーを返す可能性は否定できません。

このあたりについては、Swift よりも Web 系の質問として質問された方がより正確な情報(マナーの良いアクセス方法について)知ることができるのではないでしょうか。

WkWebView でサーバの応答を判断するには、webView(_:decidePolicyFor:decisionHandler:) を使うべきかと思います。

Asks the delegate for permission to navigate to new content based on the specified action information.

たとえば、このような感じで Status Code を調べらるので、ここで判断するが良いのではないでしょうか(正確にやるには、ご提示のコードと同じく、全てのコードについて判断する必要があります。)。

Swift

1 func webView(_ webView: WKWebView, 2 decidePolicyFor navigationResponse: WKNavigationResponse, 3 decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) { 4 5 // Status code を調べる。 6 if let res = navigationResponse.response as? HTTPURLResponse { 7 print("Status code: ", res.statusCode) 8 9 if res.statusCode == 200 { 10 // 読み込みを続けるのであれば .allow, キャンセルするのであれば .cancel 11 decisionHandler(.allow) 12 } else { 13 print("error") 14 decisionHandler(.cancel) 15 } 16 } 17 }

200 以外の時に特定のページに飛ばしたいということであれば、たとえばこういう書き方もできます。
あくまでも「例えば」の話なので、正確性を期すのであれば、状態遷移についてかなり詳細に検討する必要がありますが、一応これでも動きます(状態遷移をよく考えないと、リロードを繰り返す可能性があります)。

Swift

1 func webView(_ webView: WKWebView, 2 decidePolicyFor navigationResponse: WKNavigationResponse, 3 decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) { 4 print(#function) 5 // navigationResponse の情報をダンプさせているだけ 6 dump(navigationResponse) 7 8 // Status code を調べる。 9 if let res = navigationResponse.response as? HTTPURLResponse { 10 print("Status code: ", res.statusCode) 11 12 if res.statusCode == 200 || res.statusCode == 462{ 13 // 読み込みを続けるのであれば .allow, キャンセルするのであれば .cancel 14 decisionHandler(.allow) 15 } else { 16 print("error") 17 decisionHandler(.cancel) 18 } 19 } 20 } 21 22 // 404 などの時に呼び出される 23 func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) { 24 print(#function) 25 26 // エラー用URL 27 let redirectURL = URL(string: "https://test.com") 28 webView.load(URLRequest(url: redirectURL!)) 29 }

投稿2020/12/26 01:12

TsukubaDepot

総合スコア5086

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問