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

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

解決済

2回答

2612閲覧

APIからのResponseで400が帰ってきてしまう

hodoru3sei

総合スコア284

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クリップ

投稿2019/09/17 14:35

編集2019/10/13 16:09

API通信で値を取得していたのですが、突然値を取得することができなくなってしまいました。
API自体の変更はなく、web上で試したところ以前と同じように値の取得ができました。

APIからデータを取得するのは【Swift】URLSessionまとめの記事を参考にさせていただいています。

Swift

1 2let task = URLSession.shared.uploadTask(with: request, from: uploadData) { data, response, error in 3 if let error = error { 4 print ("error: (error)") 5 return 6 } 7 8 //型を調べたところOptional<NSURLResponse>でした。 9 let valueType = String(describing: type(of: response)) 10 11       //このguard節の部分でHTTPURLResponseにキャストできずに失敗してしまします。 12 guard let response = response as? HTTPURLResponse, 13 (200...299).contains(response.statusCode) else { 14 print ("server error") 15 return 16 } 17 18 guard let data = data, let jsonData = try? JSONDecoder().decode(API.self, from: data) else { 19 print("json conversion failed") 20 return 21 } 22 result(jsonData.converted) 23 } 24 task.resume() 25 }

NSURLResponse型をHTTPURLResponseにしてデータを取り出したいのですがどうしたら良いのでしょうか?

追記

いただいたアドバイスを参考に以下のコードで調べてみたところresponseCodeで400がかえってきてしまっているようでした。

guard let response = response as? HTTPURLResponse else { return } let code = response.statusCode if !(200...299).contains(response.statusCode) { return }

処理を行なっているロジック部分のコードは以下になります。ひらがな化APIのコンソールで試すと問題なく翻訳された値が帰ってきます。
どこが間違っているのでしょうか?

struct PostData: Codable { var app_id:String var request_id: String var sentence: String var output_type: String } ...省略 override func viewDidLoad() { super.viewDidLoad() let url = URL(string: "https://labs.goo.ne.jp/api/hiragana") var request = URLRequest(url: url!) request.httpMethod = "POST" request.addValue("application/json", forHTTPHeaderField: "Content-Type") request.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type") let postData = PostData(app_id: "作成したID", request_id: "record003", sentence: "漢字が含まれた文章", output_type: "hiragana") guard let uploadData = try? JSONEncoder().encode(postData) else { return } request.httpBody = uploadData let task = URLSession.shared.uploadTask(with: request, from: uploadData) { data, response, error in if let error = error { print ("error: (error)") return } guard let response = response as? HTTPURLResponse, (200...299).contains(response.statusCode) else { print ("server error") return } if let mimeType = response.mimeType, mimeType == "application/json", let data = data, let dataString = String(data: data, encoding: .utf8) { print ("got data: (dataString)") } } task.resume() }

追記その2

uploadDataの値をstrihg型に変換してみたところ以下のような値が出力されました

{"output_type":"hiragana","request_id":"record003","app_id":"作成したID","sentence":"変換する文字列"}

サイトにサンプルとして用意されていた入力例のjsonは以下のものでした

{"app_id":"[発行されたapp_id]", "request_id":"record003", "sentence":"漢字が混ざっている文章", "output_type":"hiragana"}

json自体に間違いはなさそうなんですがpostしている部分が間違っているのでしょうか?それともAPI自体に何か問題があるのでしょうか

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

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

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

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

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

takabosoft

2019/09/18 01:07

回答者の手元で再現させられるようなものでないと回答は付かないかもしれませんね・・・ guard let response = response as? HTTPURLResponse, (200...299).contains(response.statusCode) else { の部分はキャストとstatusCodeのチェックが両方行われているように見えますが、 キャストは成功していたりしませんか?問題箇所の切り分けのために2つのguard letに別けてみてはいかがでしょう。
takabosoft

2019/09/18 01:09

もし本当にキャストに失敗しているのであれば、responseは何型になっているのか調べてみてください。
hodoru3sei

2019/10/11 14:17

よくよく調べてみるとキャスト自体はできたいるようなのですが、(200...299).contains(response.statusCode)こっちの方で引っかかちゃっているようでした。
guest

回答2

0

自己解決

リクエストパラメータのオプションにapplication/x-www-form-urlencodedをせっていしていたことがもんだいでした。
json形式のパラーメータに変えたら正常にとれました

投稿2019/10/14 09:49

hodoru3sei

総合スコア284

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

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

0

急にエラーが出るようになって、レスポンスコードが、400 ということですが、コードと一緒にエラーメッセージも返ってきていると思いますが、どのようなメッセージ返ってきていますか?

もし、メッセージが Rate limit exceeded であれば、「app_idが利用上限(3,000 call/日)を超えている。」ということなので、利用回数がリセットされるか上限以下になるまで、待つしかないと思います。

APIのエラーレスポンスについて 参照。

投稿2019/10/11 22:26

CHERRY

総合スコア25171

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

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

hodoru3sei

2019/10/12 03:12

ありがとうございます、responseで帰ってきたerrorを確認してみたのですがnilでした...
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問