web-dev-qa-db-ja.com

エラーからサーバー応答メッセージを取得する

私のサーバー(CakePHP)は次のように応答しています:

$this->response->statusCode('400');
$this->response->type('json');
$this->response->body(json_encode(array('message' => 'Bookmark already exists')));

Postmanの出力は、期待どおりになります。

{"メッセージ": "ブックマークは既に存在します"}

問題は、障害ハンドラー(Alamofire 3.1.3 + SwiftyJSON 2.3.2)からこのメッセージにアクセスする方法が見つからないことです。

Alamofire.request(.POST...
.validate()
.responseJSON { response in

switch response.result {

case .Success(_):                           
// All good

case .Failure(let error):
// Status code 400                 
print(response.request)  // original URL request
print(response.response) // URL response
print(response.data)     // server data
print(response.result)

Response.dataをJSONにキャストする方法が見つかりません。単にnilを取得し、結果がFAILUREを返すだけです。

障害ハンドラーからこのサーバーメッセージにアクセスする方法はありますか?

9
tompa

Alamofire 3.0移行ガイド の.Failureケースでは、データは解析されません。ただし、サーバーデータは引き続きresponse.dataで利用可能であり、解析できます。

これを手動で解析するには、以下が機能するはずです。

Alamofire.request(.POST, "https://example.com/create", parameters: ["foo": "bar"])
  .validate()
  .responseJSON { response in
     switch response.result {
     case .Success:
         print("Validation Successful")
     case .Failure(_):
          var errorMessage = "General error message"

          if let data = response.data {
            let responseJSON = JSON(data: data)

            if let message: String = responseJSON["message"].stringValue {
              if !message.isEmpty {
                errorMessage = message
              }
            }
          }

          print(errorMessage) //Contains General error message or specific.
     }
  }
}

これは SwiftyJSON を使用し、NSDataを変換するためのJSON構造体を提供します。 NSDataのJSONへの解析は、SwiftyJSONなしで実行できます。答えは ここ です。

もう1つのよりクリーンなオプションは、 Custom Response Serializer を作成することです。

19
Shawn Aukstak

ルーターを使用し、SwiftyJSONを使用しない方法:

Alamofire.request(APIRouter.Register(params: params)).validate().responseJSON { response in
    switch response.result {
        case .Success(let json):
            let message = json["clientMessage"] as? String
            completion(.Success(message ?? "Success"))
        case .Failure(let error):
            var errorString: String?

            if let data = response.data {
               if let json = try? NSJSONSerialization.JSONObjectWithData(data, options: []) as! [String: String] {
                   errorString = json["error"]
               }
            }

            completion(.Error(errorString ?? error.localizedDescription))
        }
   }
6
SoftDesigner

次の行を使用して、Alamofireリクエストからの応答本文を読み取りました。

    Alamofire.request(.POST, serveraddress, headers: headers, encoding: .JSON)
        .response{ request, response, data, error in
            let responseData = String(data: data!, encoding: NSUTF8StringEncoding)
            print(responseData)


    }

この本体を使用すると、カスタムサーバー応答エラーメッセージを受け取ることができます。

宜しくお願いします

5
BHuelse

Alamofire 4.0以降の場合:

このresponse.response?.statusCodeを試してください

url:「あなたのURL」

パラメータ:「YOURPARAMETERDICTIONARY」

ヘッダー:「YOURHEADERDICTIONARY」

JSON解析にSwiftyJSONを使用しています

サンプルリクエストはこちらです:

func createPostRequestWith(path: String?,
                          parameters: [String : Any]? = nil,
                          success : @escaping (Any?) -> (),
                          failure : @escaping (NSError) -> ()) {

    if !(Alamofire.NetworkReachabilityManager()?.isReachable)! {
        let error = NSError(domain: "", code: -1003, userInfo: nil)
        failure(error)
    } else {
        guard let url = path else { return }
        Alamofire.request(url, method: .post, parameters: parameters, encoding: JSONEncoding.default, headers: createCurrentHeader()).validate(statusCode: 200..<300).responseJSON {
            response in
            switch response.result {
            //Remove loader here either after parsing or on error
            case .success(let data):
                success(data)
            case .failure(let error):
                print(error)
                if let responseData = response.data {
                    var parsedResponseData = JSON.init(data: responseData)
                    let customError = NSError(domain: parsedResponseData["message"].stringValue, code: response.response?.statusCode ?? 555, userInfo: nil)
                    failure(customError as NSError)
                } else {
                    failure(error as NSError)
                }
            }
        }
    }
}
0