Alamofire with Swift using a Get - swift

I am using Alamofire with Swift 5 and using a get to send some parameters while a Post works the following fails, any idea of how this should be used. If I remove the parameters it works .
let parameters:Parameters = ["SiteKey": "abcdef"]
AF.request(url, method: .get,parameters:parameters,encoding: JSONEncoding.default,headers:headers )
Any help is appreciated

It's clearly implied from the results that you've got. A GET request cannot contain parameters in its body, a POST request can. Get request should be something when you paste the URL in a browser and you should get the response in the browser.
In your case it's either not GET request or you need to send the parameters as url-encoded.
AF.request(url, method: .get, parameters: parameters, encoding: URLEncoding(destination: .queryString), headers: headers)

Related

What are some differences between encoding vs content-type in Alamofire

Alamofire.request(url, method: .post, parameters: param, encoding: JSONEncoding.default, headers: [content-type: multipart/form-data])
In header of request I see that there a field called content-type which can be set as application/json, application/x-www-form-urlencoded, multipart/form-data. But the problem is that in encoding param we can also set as JSONEncoding.default. Then what are some differences between encoding vs content-type in Alamofire.
encoding: for parameter which we sending to server
content-type: for specifying the response type
The encoding parameter sets how should Alamofire parse the passed parameters. For example, if it's set to URLEncoding.default, Alamofire will append the parameters to the URL.
The Content-Type header, on the other hand, tells the web server what type of content do we want to semd.
From the MDN web docs:
The Content-Type entity header is used to indicate the media type of the resource.
In responses, a Content-Type header tells the client what the content type of the returned content actually is.
Since Alamofire is an HTTP request wrapper, it provides a parameter for settings HTTP headers. As described by W3C, HTTP headers define how your request will be handled by server : W3C' Header Field Definitions.
An additional encoding parameter is available in Alamofire since you have to describe how to format an input response. Briefly, server cannot understand how to process a Swift Array or Dictionary, you need to explicitly write what kind of encoding is required. Alamofire provides several solutions to encode Swift object : Alamofire Encoding Options.
In this way, according to your request method (PUT, GET, POST, ...) you could have an Header ["Accept": "application/json"] and differents Alamofire encoding options.

How to set Content-Type in swift3 alamofire

I am sending data in JSON with content-type JSON but this shows me the content-type XML.
So the server could not read my request.
Also, that is the post request
The problem is that you are using .responseJSON which tells Alamofire that the response would contain JSON. Since the response is XML and not JSON in your case, Alamofire would throw an error. What you need instead is not to specify the response type and then an XMLParser to parse the data. One option is SWXMLHash. Your updated code would look something like this
Alamofire.request(request)
.response { response in
var xml = SWXMLHash.parse(response.data!)
}
Basically, this is not an error of content-type. this is an error of data type.
I send the all value in the string but there is need to send the data with data type.
When I request with data type it automatically changed content-type in JSON.

Alamofire error with JSON response

I have been struggling with Alamofire issue for days and I'm not sure if it's from the backend or the way I structure my code.
Here is the issue:
when I text my API with Postman I get the correct response if I hit the params button and add the parameters Notice the lower body is empty but the upper one is filled with parameters
However, when I use the lower parameters with the same info I get an error with no JSON. Also same error appears in Xcode when I try to call the API with the same link
this is Xcode Alamofire error
FAILURE: responseSerializationFailed(Alamofire.AFError.ResponseSerializationFailureReason.jsonSerializationFailed(Error Domain=NSCocoaErrorDomain Code=3840 "Invalid value around character 0." UserInfo={NSDebugDescription=Invalid value around character 0.}))
and here is Postman error
and finally this is my code to call API:
let urlStr = "api/client/meal_add"
let url = URL(string: urlStr)
let para = ["meal_id": "31",
"user_id": "2",
"qty":"2"]
let headers: HTTPHeaders = [
"Auth": "Auth" // Edited for security
]
Alamofire.request(url!, method: .post, parameters: para,encoding: URLEncoding.default, headers: headers).responseJSON { response in
print(response)
print(response.result.debugDescription)
if let value : AnyObject = response.result.value as AnyObject {
it used to work perfectly 5 days ago but I have no idea why it stoped. Also In other View Controllers I do HTTP calls to the same API and the responses have no issues, only this one.
First, I want to talk about the difference between HTTP get and post request. Get request is putting parameters in url. They are appended to the url in this format
URL?key1=value1&key2=value2
The RESTful hanlder for that URL will then parse the key value pair and use them. When you click on the param button in your postman, it actuall doing this append param to url thing. However this get into problem when you have lots of param. Usually, an url will have some problem if it exceeds length 8000. So a post request is actually nesting the parameters inside the request, not on the url. So normally in a post request, you will only see the URL, not the ?key1=value1&key2=value2 part.
Back to your problem, I have no idea how your server side handles this post request with parameters in url but since an empty post request with param in url works, in your swift code, you can simply append the param in your url and do a post request with no parameters.
let urlStr = "api/client/meal_add?meal_id=31&user_id=2&qty=2"
let url = URL(string: urlStr)
Alamofire.request(url!, method: .post, parameters: [],encoding: URLEncoding.default, headers: headers).responseJSON { response in
Moving forward, I strongly recommand you to have a look at your server side to make sure your post request is written in the correct way

Swift 3 Uploading data to a server with Alamofire

I'm currently using alamofire to request data from a web service.Everything works great but I have a doubt about how to upload data to my server with the method get.
Example of web service --> http://www.google.com/id=2&name=trump&message=fakenews
I tried to use the traditional alamofire.request("weberservice") but It didn't work.
How do I send this information using alamofire?
What you want to do is make a POST request. This sends data to the server.
What you will do is use the request method, but add an additional argument for the HTTP method:
Alamofire.request("<YOUR-URL>", method: .post)
The Alamofire docs here talk about passing the data to the server when you make the POST request. You basically add a 3rd argument with the dictionary:
let parameters: Parameters = ["foo": "bar"]
// All three of these calls are equivalent
Alamofire.request("https://httpbin.org/get", parameters: parameters)
// https://httpbin.org/get?foo=bar
From the Alamofire docs

Preventing NSURLSession default HTTP headers

I'm trying to craft a very specific HTTP request to a server (ie. defining the exact set of HTTP headers), but NSURLSession keeps "helpfully" inserting a bunch of HTTP headers like Accept, Accept-Language and Accept-Encoding.
Consider the following playground (Swift 2.x) which sends a request to a service that just echos the HTTP headers that were sent:
import Foundation
import XCPlayground
XCPlaygroundPage.currentPage.needsIndefiniteExecution = true
let url = NSURL(string: "http://httpbin.org/headers")!
let request = NSMutableURLRequest(URL: url, cachePolicy: .ReloadIgnoringLocalCacheData, timeoutInterval: 30000)
let configuration = NSURLSessionConfiguration.ephemeralSessionConfiguration()
let session = NSURLSession(configuration: configuration)
let task = session.dataTaskWithRequest(request) { (data: NSData?, response: NSURLResponse?, error: NSError?) in
print(NSString(data: data!, encoding: NSUTF8StringEncoding))
XCPlaygroundPage.currentPage.finishExecution()
}
task.resume()
You can see that there are three Accept headers being sent. How can I prevent that?
I've tried setting the header using request.setValue(nil, forHTTPHeaderField: "Accept-Language") but that gets ignored. Tried setting it to "", but no good. I've also tried manipulating the HTTPAdditionalHeaders property on NSURLSessionConfiguration, but no love.
How do I get NSURLSession to not be quite so helpful?
I doubt what you're asking for is possible. NSURLSession (and NSURLConnection) automatically provide a number of headers, and that's one of them.
There's also no valid reason to remove them. All three of those headers have been part of the spec since the original HTTP/0.9 spec (https://www.w3.org/Protocols/HTTP/HTRQ_Headers.html). There's absolutely no excuse for any server not either handling those correctly or ignoring them outright.
With that said, if you provide the wrong value for those fields (and the default may be wrong), the server may refuse to give you results. To solve that problem, first figure out what type of data the server is actually going to provide, and specify that value in the Accept header instead of the default.
For example, you might set Accept to "application/json" or one of the other variants (What is the correct JSON content type?) if you're expecting JSON data.
That said, if you really must avoid having those headers sent, you can always open a socket, construct the request manually, and send it. Assuming the server doesn't require chunked encoding, it is pretty easy to do. (Chunked encoding, however, is a horror of Herculean proportions, so if your server sends that back, you'll pretty much have to resort to adding libcurl into your project and using that to make requests instead.)