私のサーバー(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を返すだけです。
障害ハンドラーからこのサーバーメッセージにアクセスする方法はありますか?
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 を作成することです。
ルーターを使用し、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))
}
}
次の行を使用して、Alamofireリクエストからの応答本文を読み取りました。
Alamofire.request(.POST, serveraddress, headers: headers, encoding: .JSON)
.response{ request, response, data, error in
let responseData = String(data: data!, encoding: NSUTF8StringEncoding)
print(responseData)
}
この本体を使用すると、カスタムサーバー応答エラーメッセージを受け取ることができます。
宜しくお願いします
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)
}
}
}
}
}