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

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

ただいまの
回答率

89.23%

URLSessionのPOSTについて

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 941

hodoru3sei

score 119

https://labs.goo.ne.jp/api/jp/hiragana-translation/リンク先のAPIに対してPostを行いたいと考えているのですが、エラーコードが帰ってきてしまいます。

コード

上記2つのサイトを参考にPOSTの処理を試してみました。

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")

        let params: [String: Any] = [
            "app_id": "作成したapp_id",
            "request_id": "", "sentence": "焼き芋",
            "output_type": "hiragana"
        ]

        do {
            request.httpBody = try JSONSerialization.data(withJSONObject: params, options: .prettyPrinted)
            let task:URLSessionDataTask = URLSession.shared.dataTask(with: request as URLRequest, completionHandler: {(data,response,error) -> Void in
                let resultData = String(data: data!, encoding: .utf8)!
                print("result:\(resultData)")
                print("response:\(response)")
            })
            task.resume()
        } catch {
            print("Error:\(error)")
        }
    }

通信自体はできていそうなのですが、printしているdataの中身を見るとエラーコードが帰ってきているようでした。

ログ

コンソールのログは以下の様に表示されます

result:{"error_code": -1}
response:Optional(<NSHTTPURLResponse: 0x280d10600> { URL: https://labs.goo.ne.jp/api/hiragana } { Status Code: 400, Headers {
    "Content-Length" =     (
        18
    );
    "Content-Type" =     (
        "application/json; charset=UTF-8"
    );
    Date =     (
        "Mon, 24 Jun 2019 07:52:09 GMT"
    );
    P3P =     (
        "policyref=\"/w3c/p3p.xml\",CP=\"CAO DSP COR CURa ADMa DEVa TAIa PSAa PSDa IVAi IVDi CONo OUR SAMo OTRo IND PHY ONL UNI PUR FIN COM NAV INT DEM CNT STA HEA PRE LOC\""
    );
    "Set-Cookie" =     (
        "BIGipServerpool-labs-10-2=121902252.20480.0000; path=/; Httponly; Secure",

z        "TS019127ff=0122c0d7568a528128b5cbc18a059c3de65549546b5e4e4ab05960f1736a72e4f9ea16d828b26345fb2b59c0b617cb4abed40454be27f9bd990125b068de0eacb03dbd61ff; Path=/"
    );
    "X-Cnection" =     (
        close
    );
    "X-Content-Type-Options" =     (
        nosniff
    );
} })

APIにPOSTを行った経験がないので何が悪いのか検討がつかず困っています。何が間違っているのでしょうか?

追記

公式ドキュメントを読んで以下の様なコードに書き換えてみたのですがserver errorの部分に入ってしまいます。

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: "作成したapp_id", request_id: "", 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()
    }
}
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+2

HTTPステータス400は一般的にはBad Requestの意味なので、リクエストの仕方が間違っているのだと思います(そのサイトの説明にはないので違う可能性はありますが)。
POSTの送信の仕方は見た感じ最初のコードで問題ないと思います。

後はそのAPIを使ったことないので想像になりますが…

  • request_idが空なのが許されないのかも? request_idを送らないようにするか適当な文字列を指定して試してみては?
  • "作成したapp_id"の部分は自分のapp_idに置き換えてありますよね?

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/06/25 10:09

    回答ありがとうございます!
    app_idは作成したものを入力しています!

    API公開ページでrequest_id入れなくても値取得できていた様だったので省略しちゃってました。
    request_id辺りで色々試してみようと思います!

    キャンセル

  • 2019/06/25 10:50

    サンプルに記載があったrequest_idを使ったら成功しました!
    ありがとうございます‼︎自分では全く気づきませんでした

    キャンセル

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

  • ただいまの回答率 89.23%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる