web-dev-qa-db-ja.com

Alamofireは、エラーHTTPステータスコードで.Successを返します

私が苦労している非常に単純なシナリオがあります。 Alamofireを使用して、ユーザーをREST APIに登録しています。最初の登録呼び出しは成功し、ユーザーはログインできます。2番目の呼び出しは、同じ電子メールアドレスで登録しようとすると、サーバーからHTTPステータスコード409が返されます。ただし、Alamofireは、空の要求と応答で.Successを返します。このAPIをpostmanでテストしましたが、409を正しく返します。

Alamofireが.Failure(error)を返さないのはなぜですか?エラーにはステータスコード情報などがありますか?

毎回同じ入力で実行する呼び出しを次に示します。

Alamofire.request(.POST, "http://localhost:8883/api/0.1/parent", parameters: registrationModel.getParentCandidateDictionary(), encoding: .JSON).response(completionHandler: { (req, res, d, e) -> Void in
        print(req, res, d, e)
    })
25
Craigt

Alamofireから 手動

検証

デフォルトでは、Alamofireは、応答の内容に関係なく、完了した要求を成功したものとして扱います。応答に受け入れられないステータスコードまたはMIMEタイプが含まれている場合、応答ハンドラーの前にvalidateを呼び出すと、エラーが生成されます。

もう一度、マニュアルのvalidateメソッドを使用して、ステータスコードを手動で検証できます。

Alamofire.request(.GET, "https://httpbin.org/get", parameters: ["foo": "bar"])
     .validate(statusCode: 200..<300)
     .validate(contentType: ["application/json"])
     .response { response in
         print(response)
     }

または、引数なしのvalidateを使用して、ステータスコードとコンテンツタイプを半自動的に検証できます。

Alamofire.request(.GET, "https://httpbin.org/get", parameters: ["foo": "bar"])
     .validate()
     .responseJSON { response in
         switch response.result {
         case .success:
             print("Validation Successful")
         case .failure(let error):
             print(error)
         }
     }
65
David Berry

responseを使用している場合、NSHTTPURLResponseパラメーターを確認できます。

Alamofire.request(urlString, method: .post, parameters: registrationModel.getParentCandidateDictionary(), encoding: JSONEncoding.default)
    .response { response in
        if response.response?.statusCode == 409 {
            // handle as appropriate
        }
}

デフォルトでは、4xxステータスコードはエラーとして処理されませんが、validateを使用してエラーを処理し、より広範なエラー処理に組み込むことができます。

Alamofire.request(urlString, method: .post, parameters: registrationModel.getParentCandidateDictionary(), encoding: JSONEncoding.default)
    .validate()
    .response() { response in
        guard response.error == nil else {
            // handle error (including validate error) here, e.g.

            if response.response?.statusCode == 409 {
                // handle 409 here
            }
            return
        }
        // handle success here
}

または、responseJSONを使用している場合:

Alamofire.request(urlString, method: .post, parameters: registrationModel.getParentCandidateDictionary(), encoding: JSONEncoding.default)
.validate()
.responseJSON() { response in
    switch response.result {
    case .failure:
        // handle errors (including `validate` errors) here

        if let statusCode = response.response?.statusCode {
            if statusCode == 409 {
                // handle 409 specific error here, if you want
            }
        }
    case .success(let value):
        // handle success here
        print(value)
    }
}

上記はAlamofire 4.xです。 Alamofireの以前のバージョン については、この回答の以前の表現を参照してください。

14
Rob

validate()を使用すると、サーバーからエラーメッセージが失われます。それを保持する場合は、この回答を参照してください https://stackoverflow.com/a/36333378/1261547

5
Lilo