not receiving json Data in Alamofire request with http body - json

Im using the following code to send a POST request to the web server with an http parameter, in order to receive the JSON Data
Alamofire.request(.POST,myURL, parameters: [:], encoding: .Custom({
(convertible, params) in
var mutableRequest = convertible.URLRequest.copy() as NSMutableURLRequest
mutableRequest.HTTPBody = "MyBody".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)
return (mutableRequest, nil)
}))
ive got it from stackoverflow : POST request with a simple string in body with Alamofire
but im not receiving any data.
im using swift 2.3 and alamofire 3.5.
Any help?

simple POST call with Alamofire4 & Swift3 :
let url: String = "https://example.com"
let parameter = ["X": "10", "Y": "20"]
Alamofire.request(url, method: .post, parameters: parameter, encoding: URLEncoding.default, headers: nil)
.responseJSON { (response) in
let result = response.result.value
print(result)
}
simple GET call to see some JSON result :
let url: String = "https://example.com"
Alamofire.request(url)
.responseJSON { response in
let result = response.result.value
print(result)
}

Related

Alamofire POST not working as expected. Error on parameters

I am trying to upload (post) a JSON string using Alamofire and I'm getting an error that leads me to believe there is some issue in the dictionary encoding.
The array I am encoding is an array of objects, all of type String. It looks like this:
class SavedDeliveries: Codable { //not sure if this is the issue (I use this to store default values locally)
var fullName = ""
var address = ""
var city = ""
var zip = ""
var phone = ""
var orders = ""
var ordersListed = ""
var pickup = ""
}
The code including the Alamofire call looks like this:
func postData() {
let headers: HTTPHeaders = [
"Content-Type": "application/json",
"X-Master-Key": "xxx", //API Key
"X-Bin-Name": "deliverydata"]
let jsonEncoder = JSONEncoder()
let jsonData = try! jsonEncoder.encode(deliveryList)
let json = String(data: jsonData, encoding: String.Encoding.utf8)
print(json!) // printing the JSON and it is correct when validated.
AF.request("https://api.jsonbin.io/v3/b", method: .post, parameters: json, encoding: JSONEncoding.default, headers: headers).responseString { (response) in
switch response.result {
case .success:
print("was successful")
case let .failure(error):
print(error)
}
}
}
I expect it to upload the JSON file but I'm getting an error message that says this:
Cannot convert value of type 'String?' to expected argument type 'Parameters?' (aka 'Optional<Dictionary<String, Any>>')
Not sure if the AF call parameter is expecting a certain kind of dictionary key:value format. If this is not the right call format for uploading JSON, what do I need to change?
Thanks for any help. I'm not a full-time Swift developer but manage an app that is usually within my capabilities. This one has me stumped.
I guess I don't understand much about HTTP requests or Alamofire, but I was able to solve this issue with the following mods to my code (without Alamofire, which seems like overkill in this case).
func postData() {
// Prepare URL
let url = URL(string: "https://api.jsonbin.io/v3/b")
guard let requestUrl = url else { fatalError() }
// Prepare URL Request Object
var request = URLRequest(url: requestUrl)
request.httpMethod = "POST"
// Set HTTP Request Body
let header: HTTPHeaders = [
"Content-Type": "application/json",
"X-Master-Key": "xxx",
"X-Bin-Name": "deliverydata"
]
request.headers = header
let jsonEncoder = JSONEncoder()
let jsonData = try! jsonEncoder.encode(deliveryList)
let json = String(data: jsonData, encoding: String.Encoding.utf8)
request.httpBody = json!.data(using: String.Encoding.utf8)
// Perform HTTP Request
let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
// Check for Error
if let error = error {
print("Error took place \(error)")
return
}
// Convert HTTP Response Data to a String
if let data = data, let dataString = String(data: data, encoding: .utf8) {
print("Response data string:\n \(dataString)")
}
}
task.resume()
}
To make such a request using Alamofire, I'd recommend:
let headers: HTTPHeaders = [
"Content-Type": "application/json",
"X-Master-Key": "xxx", //API Key
"X-Bin-Name": "deliverydata"]
AF.request("https://api.jsonbin.io/v3/b",
method: .post,
parameters: deliveryList,
headers: headers).responseString { response in
switch response.result {
case .success:
print("was successful")
case let .failure(error):
print(error)
}
}
Even better, create a Decodable response type and use responseDecodable to parse it.
I would also suggest not using empty strings as your default values, that can easily lead to sending bad or invalid data to the backend.

Alamofire - POST request with JSON giving 301

I want to send POST request with JSON, I'm expecting JSON object with auth_token and refresh_token in response. My code looks like this:
let headers: HTTPHeaders = [
"Authorization": "Basic " + data.toBase64() //data is just string needed for authentication
]
// this should be a JSON
let parameters = [
"code": self.code,
"grant_type": "authorization_code",
"redirect_uri": "populi://callback"
]
Alamofire.request("https://populi.pl/api/v1/auth/token", method: .post, parameters: parameters, encoding: JSONEncoding.default, headers: headers).responseString { response in
print(response.request)
print("\n3 RESPONSE : \(response)")
print("\n3 POST : \(response.response)")
print("\n3 DATA : \(response.data)")
print("\n3 RESPONSE RESULT : \(response.result)")
print("\n3 RESPONSE RESULT VALUE : \(response.result.value)")
print("3 ERROR : \(response.error)")
}
Yeah, I print a lot of things, that's because I'm new to networking.
In response I'm getting 301 moved permanently. Why? I have no idea what's wrong. Is this wrong JSON in parameters or maybe something with redirecting? I should get 200 and JSON in response.
try this
func getData(){
let todoEndpoint: String = Your url
let params: Parameters = [yor parameters]
let headers: [String : String] = [
"Content-Type": "application/x-www-form-urlencoded",
]
Alamofire.request(todoEndpoint, method: .post, parameters: params,headers: headers)
.responseJSON { response in
switch response.result {
case .success:
let json = JSON(response.result.value as Any)
print(json)
break
case .failure(let error):
print(error)
}
}
}
I solved this with "/" at the end of request URL.
I was using URLSession for requests and was getting 301 for 1 request
then I tried Alamofire and still got the same response and at the end, I figured out that issue was that I was not appending / at the end of endpoint

How to send multiple JSON objects as a stream using alamofire

I want to send multiple different JSON object in a single request, i felt streaming the multiple JSON objects like a file in a single request would be better, so kindly let me know if it is possible, if so kindly give me an idea of how to do it using Alamofire, Below is the formate of the raw body (application/json) data that i want to post
{"a":23214,"b":54674,"c":"aa12234","d":4634}
{"a":32214,"b":324674,"c":"as344234","d":23434}
{"a":567214,"b":89674,"c":"sdf54234","d"34634}
I tried the below code, but it didn't work as the body param is not in the correct format, that's the reason i want to try sending the multiple JSON objects as a stream in a single request, Kindly advice
let SendParams = [
["a":1234, "b":2345, "c":3456], ["a":2345, "b":3456, "c":4567], ["a":3456, "b":4567, "c":5678]
]
_ = Alamofire.request(url, method: .post, parameters: params, encoding: JSONEncoding, headers: header)
JSON format is not correct for your request, JSON is always key-value pair, where key is always String, and value is any Object. In your example need to set key at top level for object of type Array as below:
let SendParams = [
"key" :[["a":1234, "b":2345, "c":3456], ["a":2345, "b":3456, "c":4567], ["a":3456, "b":4567, "c":5678]]
]
_ = Alamofire.request(url, method: .post, parameters: SendParams, encoding: JSONEncoding.default, headers: headers).responseJSON { (response) in}
OR
Serialise the array and set as httpBody of URLRequest object:
let url = YOUR_POST_API_URL
var request = URLRequest(url: URL(string: url)!)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
let values = [
["a":1234, "b":2345, "c":3456], ["a":2345, "b":3456, "c":4567], ["a":3456, "b":4567, "c":5678]
]
request.httpBody = try! JSONSerialization.data(withJSONObject: values)
Alamofire.request(request)
.responseJSON { response in
// do whatever you want here
switch response.result {
case .failure(let error):
print(error)
if let data = response.data, let responseString = String(data: data, encoding: .utf8) {
print(responseString)
}
case .success(let responseObject):
print(responseObject)
}
}

JSON parse error from server when making request with Alamofire in swift 4

I need to make a post request to the api and obtain data from the response. The api returns the following response:
{
valid: true
}
or
{
valid: false
}
My Alamofire request looks something like this:
parameters = ["key": "somekey"]
let headers: HTTPHeaders = [
"Content-Type": "application/json",
"Authorization": "JWT \(token)"
]
Alamofire.request(baseURL, method: .post, parameters: parameters, headers: headers).responseJSON{
response in
if let result = response.result.value {
let JSON = result as! NSDictionary
print(JSON) //{ detail = "JSON parse error - Expecting value: line 1 column 1 (char 0)"}
}
I can't seem to be able to get the JSON data from the server to extract the value of valid. Instead I get the error: detail = "JSON parse error - Expecting value: line 1 column 1 (char 0)" from the server
Turns out I wasn't including one important parameter in the request encoding: JSONEncoding.default.(I guess the order matters) Here's what worked:
parameters = ["key": "somekey"]
let headers: HTTPHeaders = [
"Content-Type": "application/json",
"Authorization": "JWT \(token)"
]
Alamofire.request(baseURL, method: .post, parameters: parameters, encoding: JSONEncoding.default, headers: headers)
.responseJSON{
response in
if let result = response.result.value {
let JSON = result as! NSDictionary
print(JSON) //SUCCESS :{valid: 0}
}

Alamofire 4, Swift 3 and building a json body

{"title":"exampleTitle","hashTags":[{"name":"tag1"},{"name":"tag2"}],"uploadFiles":
[{"fileBytes":"seriesOfBytes\n","filename":"upload.txt"}]}
That is my desired body I want to send to the backend.
I'm using Swift 3.0 and Alamofire 4 and i have multiple questions.
first, How do i correctly create a body which contains values and arrays of values?
My approach is:
let para:NSMutableDictionary = NSMutableDictionary()
para.setValue("exampleTitle", forKey: "title")
let jsonData = try! JSONSerialization.data(withJSONObject: para, options: .init(rawValue: 0))
let jsonString = NSString(data: jsonData, encoding: String.Encoding.utf8.rawValue) as! String
print(jsonString)
which gives me
{"title":"exampleTitle"}
second, my alamofire .post request looks like the following and is not working:
Alamofire.request(postURL, method: .post, parameters: jsonString, encoding: JSONEncoding.default)
.responseJSON { response in
debugPrint(response)
}
i get the error message: extra argument 'method' in call. If i instead of jsonString use a string of the type
var jsonString: [String : Any]
it does work, but i do not know how to put the body into this type.
summary
looking for help (example would be the best) on how to create the body, and how to send it via Alamofire 4 and swift 3 to my backend.
You need to pass parameter as [String:Any] dictionary, so create one dictionary as your passing JSON like this.
let params = [
"title":"exampleTitle",
"hashTags": [["name":"tag1"],["name":"tag2"]],
"uploadFiles":[["fileBytes":"seriesOfBytes\n","filename":"upload.txt"]]
]
Now pass this params as parameter in Alamofire request.
Alamofire.request(postURL, method: .post, parameters: params, encoding: JSONEncoding.default)
.responseJSON { response in
debugPrint(response)
}