2015-09-15 3 views
0

Недавно я обновился до Alamofire 2.0, и теперь мой запрос на Put не работает с ошибкой 400, когда он ранее работал правильно. Я выполнить вызов с кодом:Положить запрос с ошибкой с Alamofire 2.0

Alamofire.request(Router.Put(query: url, params: params, encoding: .JSON)) 
    .validate() 
    .responseJSON() { 
     (request, response, result) in 

     print("request: \(request)") 
     print("response: \(response)") 
     print("result: \(result)") 

     switch result { 
     case .Success(_): 
      // success 
     case .Failure(let data, _): 
      // error occured 
     } 
} 

и мой пользовательский класс Router:

enum Router: URLRequestConvertible { 

    case Get(query: String, params: [String: AnyObject]?) 
    case Post(query: String, params: [String: AnyObject]?) 
    case Put(query: String, params: [String: AnyObject]?, encoding: ParameterEncoding) 
    case Delete(query: String, params: [String: AnyObject]?) 

    var URLRequest: NSMutableURLRequest { 
     var encodeMethod: Alamofire.ParameterEncoding = Alamofire.ParameterEncoding.URL 

     // Default to GET 
     var httpMethod: String = Alamofire.Method.GET.rawValue 

     let (path, parameters): (String, [String: AnyObject]?) = { 
      switch self { 
      case .Get(let query, let params): 
       // Set the request call 
       httpMethod = Alamofire.Method.GET.rawValue 
       // Return the query 
       return (query, params) 
      case .Post(let query, let params): 
       // Set the request call 
       httpMethod = Alamofire.Method.POST.rawValue 
       // Return the query 
       return (query, params) 
      case .Put(let query, let params, let encoding): 
       // Set the request call 
       httpMethod = Alamofire.Method.PUT.rawValue 
       // Set the encoding 
       encodeMethod = encoding 
       // Return the query 
       return (query, params) 
      case .Delete(let query, let params): 
       // Set the request call 
       httpMethod = Alamofire.Method.DELETE.rawValue 
       // Return the query 
       return (query, params) 
      } 
     }() 

     // Create the URL Request 
     let URLRequest = NSMutableURLRequest(URL: NSURL(string: Globals.BASE_URL + path)!) 
     // set header fields 
     if let key = NSUserDefaults.standardUserDefaults().stringForKey(Globals.NS_KEY_SESSION) { 
      URLRequest.setValue(key, forHTTPHeaderField: "X-XX-API") 
     } 
     // Add user agent 
     if let userAgent = NSUserDefaults.standardUserDefaults().stringForKey(Globals.NS_KEY_USER_AGENT) { 
     URLRequest.setValue(userAgent, forHTTPHeaderField: "User-Agent") 
     } 

     // Set the HTTP method 
     URLRequest.HTTPMethod = httpMethod 

     URLRequest.cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringLocalCacheData 

     return encodeMethod.encode(URLRequest, parameters: parameters).0 
    } 
} 

Вместо вызова на успех, ответ:

response: Optional(<NSHTTPURLResponse: 0x7fcee15b34d0> { URL: https://apiurl } { status code: 400, headers { 
"Cache-Control" = "no-cache"; 
"Content-Length" = 26; 
"Content-Type" = "application/json; charset=utf-8"; 
Date = "Tue, 15 Sep 2015 15:33:50 GMT"; 
Expires = "-1"; 
Pragma = "no-cache"; 
Server = "Microsoft-IIS/8.5"; 
} }) 

Я посмотрел в проблема и на стороне сервера, Content-Type приходит как пустой для запроса, когда он должен появиться как application/json. Content-Type должен автоматически добавляться, когда в запросе есть данные тела. У меня есть набор параметров:

// Save the profile 
var params: [String: AnyObject] = ["indexPhoto": userProfile.indexPhoto, 
    "dob": df.stringFromDate(userProfile.dob) as NSString, 
    "identAs": userProfile.identAs] 
// Add manually since creating the dictionary all at once is too much for swift to handle 
params.updateValue(String(format:"%.2f", userProfile.heightIn), forKey: "heightIn") 
params.updateValue(String(format:"%.2f", userProfile.weightLbs), forKey: "weightLbs") 
params.updateValue(userProfile.eyes, forKey: "eyes") 
params.updateValue(userProfile.hair, forKey: "hair") 
... 

Есть ли что-то, что я мог бы потерять с этим? До того, как я обновился до Alamofire 2.0, этот звонок работал нормально.

+0

Не могли бы вы вывести вывод 'debugPrint'' Request', который вы создаете с помощью вызова Alamofire.request'? Это, безусловно, поможет. Кроме того, вы должны попытаться использовать этот cURL, чтобы узнать, можете ли вы поразить свой сервер, как ожидалось. – cnoon

+0

$ локон -i \ \t -X PUT \ \t -H "Content-Type: применение/JSON" \ \t -H «User-Agent: Mozilla/5.0 (IOS 9,1; en_US; [ен]) BC/2.0.0.40" \ \t -H «х-ХХ-API: MYAPP х-ХХ-апи значение» \ \t -H "Accept-Language: EN-US; д = 1,0" \ \t -H «Accept- Кодирование: gzip; q = 1.0, compress; q = 0,5 "\ \t -H" User-Agent: myAppUserAgent (40; OS Version 9.1 (Build 13B5110e)) "\ \t -d" {\ "hShowCity \": true, \ "langs \": \ "168 | 169 \", ... \ "dob \": \ "1982-11-18T00: 00: 00 \"} "\ \t" https: // myAppA pi/member/profile/edit " –

+0

Я использовал' debugDescription', потому что 'Request' не имел' debugPrint'. Я вырезал некоторые параметры, потому что со всеми из них там комментарий слишком длинный для публикации. Этот API уже создан, поэтому я знаю, что конечная точка работает. Я заметил, что есть два значения «User-Agent». –

ответ

0

Возможно, есть другой способ, но я исправил ту же проблему, отправив пустые параметры вместо nil. Я не использую никаких параметров при использовании .PUT и из-за этого сервера не знает, как кодировать запрос и ответ (даже если я явно задал тип содержимого внутри заголовка, я получаю пустой тип содержимого на сервере), поэтому мое решение было отправляя пустые параметры, как в приведенном ниже коде. Надеюсь, это поможет кому-то.

var url = https://api.mysite.com/v1/issue/369613/delete 

let params = ["":""] 

let headers = NetworkConnection.addAuthorizationHeader(token, tokenType: tokenType) 
manager.request(.PUT, url, parameters: params, encoding: .JSON, headers: headers) 
     .responseJSON { response in 
      if let JSONdata = response.result.value { 
       print("JSONdata: \(JSONdata)") 
      } 
} 
Смежные вопросы