Alamofire - Bad request - ios

I am afraid I cannot share the API url. But I have checked on Postman, it works. It is a POST request and following is the response :
{
"user_key": "b0aebdedb15e2beaaf479ca3c4f8227e8e970681"
}
Postman screenshot :
In code, this is the request I am making using Alamofire :
Alamofire.request("some url", method: .post, parameters: params, encoding: URLEncoding.httpBody, headers: ["Content-Type":"application/json"])
.responseObject { (response: DataResponse<User>) in
let userResponse = response.result.value
print("")
}
But userResponse comes to be nil. This is the User object :
import ObjectMapper
class User: Mappable {
var authToken: String?
required init?(map: Map) {
}
func mapping(map: Map) {
self.authToken <- map["user_key"]
}
}
I am using ObjectMapper here.
Assuming the it is not a JSON object, I tried to handle it as a String :
Alamofire.request("some url", method: .post, parameters: params, encoding: URLEncoding.httpBody, headers: ["Content-Type":"application/json"])
.responseString { (response: DataResponse<String>) in
let dataUser = response.data as! Any
let dataUser1 = response.data as! AnyObject
let error = response.error
let code = response.response?.statusCode
print(response.value)
print(response.result.value)
}
Still, nothing. I am not able to retrieve the value. The status code however comes out to be 400 (bad request).
What exactly is it ? JSON object or String ? How do I fix this ?

Just try to replace
this URLEncoding.httpBody to JSONEncoding.default
JSONEncoding.default
Uses JSONSerialization to create a JSON representation of the parameters object, which is set as the body of the request. The Content-Type HTTP header field of an encoded request is set to application/json.
Alamofire reference

Related

Extract response data from api call in alamofire

i've read many documents about getting the response object from the api , but cant derive how to extract the data. I've used alamofire for api call . The api call is like
AF.request("http://10.177.41.163:9000/signup",
method: .post,
parameters: parameters,
encoder: JSONParameterEncoder.default).responseJSON{ response in
print(response.result)
in my print statement i get the responses as
`success({
error = {
code = PC05;
message = "User already exsists";
};
payload = {
};
success = 0;
})`
which is fine , but i want to extract suppose the error code, how to achieve that? and in general how to extract data from responses in swift.
You need to decode the jSON response, so create a Model to decode this, of course also check the response if it was successful before, you'll set an example:
Declare yourself a model:
struct RootResponse : Decodable {
var error: ErrorStruct
var payload: PayloadStruct
var success: Int
}
struct ErrorStruct: Decodable {
var code: String
var message: String
}
struct PayloadStruct : Decodable {
var ?
}
Once you've declared your model based on your jSON response, then you can switch to the function that makes the request to you:
AF.request("http://10.177.41.163:9000/signup",
method: .post,
parameters: parameters,
encoder: JSONParameterEncoder.default).responseJSON{ response in
print(response.result)
switch response.result {
case .success:
if let data = response.data {
print(data)
// Convert This in JSON
do {
let responseDecoded = try JSONDecoder().decode(RootResponse.self, from: data)
print("USER: ", responseDecoded.error.code, "Etc...")
}catch let error as NSError{
print(error)
}
}
case .failure(let error):
print("Error:", error)
}
}
I hope that's been helpful.
AF.request("http://10.177.41.163:9000/signup",
method: .post,
parameters: parameters,
encoder: JSONParameterEncoder.default).responseJSON{ response in
print(response.result)
let responseJSON = JSON(response.result) // response converted in json format
let statusCode = responseJSON["error"]["code"].stringValue // You can get status code
Note : Install pod 'SwiftyJSON' to convert response.result in JSON format.

FAILURE: responseSerializationFailed(reason: Alamofire.AFError.ResponseSerializationFailureReason.inputDataNilOrZeroLength)

I'm trying to read the JSON using Alamofire. Here is my code:
let headers = ["Content-Type": "application/json"]
func getConfirmationCode(params: [String:Any], block: #escaping(_ data : JSON, _ success : Bool) -> Void) {
if let url = URL(string: baseURL + "getConfirmationCode.php") {
Alamofire.request(url, method: .post, parameters: params, encoding: JSONEncoding.default, headers: headers).responseJSON { (response) in
DispatchQueue.main.async {
if let value = response.result.value {
let json = JSON(value)
block(json, true)
} else {
block(JSON.null, false)
}
}
}
}
}
The JSON is valid, everything works perfectly in Postman, but I can't make it work. None of the suggestions on the web helped (changing the responseJSON to responseString/responseData, changing the JSONEncoding.default to URLEncoding.default, etc.)
Can anyone help me?
You should try to check response in postman in "Preview" tab of response section. sometime it displays proper json in "Pretty" section. but in "Preview" section it many contains some print statements of API response. and those print statements makes problem in json decoding.
also, if you want to get swift code of postman response you can always get it from postman's code feature:
Hope this helps..!

Alamofire Error Token (Post) with Swift

My mates and I are working on a iOS Project, and we get stacked in this issue.
We are trying to make a POST request to our API, but all we are getting is a success code but with a reponse of type:
SUCCESS: { detail = "Authentication credentials were not provided."; }
This is our code:
#IBAction func accept(_ sender: Any) {
var comm,cat,dist : String!
comm = observationstwee.text!
print(comm)
let catd = 7
cat = String(catd)
print(cat)
dist = distancetwee.text!
print(dist)
let parameters: Parameters = [
"comment":comm,
"category":cat,
"distance":dist,
"timestamp":time
]
let headers: HTTPHeaders = ["Authorization": "Token \(token!)"]
print(headers.debugDescription)
Alamofire.request("https://llegoelbigotes.ubiqme.es/api/new-travel",parameters: parameters, headers: headers).responseJSON {response in switch(response.result) {
case .success(_):
print(response)
print("Correct Travel")
//changeViewController(storyboard_name: "Main", viewcontroller_name: "tabBarController", context: self)
break
case .failure(_):
print("FAILURE")
}
}
}
As well as with this call:
Alamofire.request("https://llegoelbigotes.ubiqme.es/api/new-travel",method:.post,parameters: parameters,headers:headers, encoding: JSONEncoding.default).validate().responseJSON
We get this:
"Extra argument 'method' in call"
Thank you so much for your help, we are working with Alamofire 4.5 and iOS 11.2
This type of error occurs when one of the parameters it’s not correct, in your example this is probably the “headers” parameter, try:
let headers = ["Authorization": "Token \(token!)"]
And check the Alamofire migration guide, you could use the RequestAdapter protocol.
when you are using post method so you need to provide the method type to the request argument code should be like that
request("https://llegoelbigotes.ubiqme.es/api/new-travel", method:
.post, parameters: parameters, encoding: JSONEncoding.default, headers:
headers).responseJSON(completionHandler:{ responseObject in
})

Replicating post method in Postman with parameters and body-raw into Alamofire

I'm having a problem on using Alamofire. When I try to post a request using a generic parameters like ["name":"John", "age":"27"] it always succeeds. But, when I try to use a web service that requires parameters and a body-raw for a base64 string I'm not able to get a successful response from the server. Though it succeeds when I use Postman. Does anyone knows how to do this on Alamofire 4? Here is the screenshot of my postman.
Thank you!
#nathan- this is the code that I used. I just assumed that the base64String inside the "let paramsDict" has a key value named "data" though it doesn't have a key name in postman.
let urlString = ApiManager.sharedInstance.formsURL + ApiManager.sharedInstance.mobileFormsImageUpload
let paramsDict = ["token": token, "fileID":"2", "filename":"images.png", "data": base64String] as [String : Any]
Alamofire.request(urlString, method: .post, parameters: paramsDict, encoding: URLEncoding.httpBody, headers: [:])
.responseJSON{ response in
switch response.result {
case .success(let data):
debugPrint("SUCCESS")
case .failure(let error):
debugPrint("Request Error")
}
}
I already figured it out. It needs a custom encoding to make it work. All the parameters must be inlined with the url so the base64 string inside the parameter is the only to be encoded. Here is the code that I used.
struct CustomPostEncoding: ParameterEncoding {
func encode(_ urlRequest: URLRequestConvertible, with parameters: Parameters?) throws -> URLRequest {
var request = try URLEncoding().encode(urlRequest, with: parameters)
let base64 = parameters?["data"] as! String
let finalBase64Format = "\"" + base64 + "\""
let postData = NSData(data: finalBase64Format.data(using: String.Encoding.utf8)!)
request.httpBody = postData as Data
return request
}
}
func uploadImageBase64(){
let jpegCompressionQuality: CGFloat = 0.9 // Set this to whatever suits your purpose
if let base64String = UIImageJPEGRepresentation(testIMG, jpegCompressionQuality)?.base64EncodedString() {
var token = String()
if let data = UserDefaults.standard.data(forKey: "userProfile"),
let user = NSKeyedUnarchiver.unarchiveObject(with: data) as? UserProfile{
token = user.token
} else {
print("There is an issue")
}
let headers = [
"content-Type": "application/json"
]
let urlString = "http://localhost/FormsService.svc/Getbase64?filename=test.png&fileID=1151&token=80977580xxx"
let paramsDict = ["data": base64String] as [String : Any]
Alamofire.request(urlString, method: .post, parameters: paramsDict, encoding: CustomPostEncoding(), headers: headers)
.responseJSON{ response in
print("response JSON \(response.result)")
}
.response{ response in
print("RESPONSE \(response)")
}
}
}

Alamofire request issue while using header

I am trying to make post request and also sending header token but it is alway giving me error. Error is "Extra argument 'method' in call". I tried many ways to fix this but not succeed.
func eventsDate(){
let postData = ["month":12,
"year": 2017]
let headerToken = defaultObject.object(forKey: KHeaderToken)
let headers = ["Authorization": headerToken]
Alamofire.request(KCalendarUrl, method: .post, parameters: postData, encoding: JSONEncoding.default, headers: headers).responseJSON(completionHandler: { response in
print(response)
//to get status code
if let status = response.response?.statusCode {
switch(status){
case 200:
print("example success")
if let result = response.result.value {
let JSON = result as! NSDictionary
}
default:
print("error with response status: \(status)")
}
}
//to get JSON return value
})
}
The headers are supposed to be of type HTTPHeaders which in turn is [String:String].
The only issue that i can think of which is happening here is that headerToken is not of String type.
Use
let headerToken = defaultObject.object(forKey: KHeaderToken) as! String
You need to make sure you are conforming to the types required by the request function. In your case, you should make sure:
KCalendarUrl is URLConvertible => It can be either a String / URL / URLComponents / URLRequest (unless you use extensions / custom types conforming to URLConvertible)
headerToken is a String (headers must be a Dictionary of both String keys and values)

Resources