iOS - HTTP Method not making POST Request but instead making GET - ios

I'm trying to make a POST call in my app using URLSession (and AlamoFire) no luck with either, I'm checking the network call on Charles Proxy and it's always being sent as a GET call even though I've specified the HTTPMethod to be "POST" or .post in both.
Weirdest part is updating the call to "DELETE" or "PUT" will work...just not "POST" or .post
I've tried just building the request from ground up in URLSession instead of using AlamoFire, tried changing the HTTPMethod (which works, just not for POST)
let session = URLSession.shared
let url = URL(string: endpointURL)!
var request = URLRequest(url: url)
request.httpMethod = "POST"
let jsonData: Data = try! requestProto.serializedData()
let task = session.uploadTask(with: request, from: jsonData) { data, response, error in
print("request made")
}
task.resume()
Expected: Charles records a POST call
Actual: Charles is recording GET call for both GET and POST calls, but DELETE and PUT are working fine.

Try this with URLSession
// create a `URLRequest` because post are urlRequest used with urlSession.shared.uploadTask
var request = URLRequest(url: url)
// here pass in data format the body of the request
request.httpBody = body
// the request method.
request.httpMethod = "post"
// required when send a json type in request
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
URLSession.shared.uploadTask(with: request, from: nil) { (data, response, error) in
let response = (response as? HTTPURLResponse)?.statusCode
if (response! == 500 ){
print("error")
}
print("request made")
}.resume()

I don't know why, but make sure that you are sending https request (not http).

Related

Is there a different way how to send a HTTP "POST" request without using third party libraries using custom header and body?

I am trying to send a HTTP "POST" request for a web-service that should return a base64 encoded picture. This is an example HTTP request for the service:
I am trying the following:
func fetchPicture(username: String, password: String) {
let url = URL(string: "https://myurl.com/download/bootcamp/image.php")!
var request = URLRequest(url: url)
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.httpMethod = "POST"
request.setValue(password.stringToSHA1Hash(), forHTTPHeaderField: "Authorization")
let postString = "username=\(username)"
request.httpBody = postString.data(using: .utf8)
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data, error == nil else { // check for fundamental networking error
print("error=\(error)")
return
}
if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 { // check for http errors
print("statusCode should be 200, but is \(httpStatus.statusCode)")
print("response = \(response)")
}
let responseString = String(data: data, encoding: .utf8)
print("responseString = \(responseString)")
}
task.resume()
}
I am getting an error 401 Unauthorized, I don't actually know whether it is because my request is bad all together or just the login initials. It would be grand if someone could go over the code and tell me if it actually corresponds to the request example shown above.
Thanks!
The first thing I notice is that you aren’t setting the request HTTP Method:
request.httpMethod = “POST”
As it turns out, I was using the CommonCrypto hashing function wrongly, I ended up using this instead:
https://github.com/apple/swift-package-manager/blob/master/Sources/Basic/SHA256.swift
And the SHA256 hash it returned was the correct one I needed, maybe this might help someone in the future.

Sending a POST request in swift but getting a 405 response (method not allowed)

Im making a POST request to the API. I have tested the API using Postman and another third party tool and Im getting a 200 response. But when I make a request from swift I get a 405 response (method not allowed) and an error message saying that "GET" request is not allowed even though clearly Im making a POST request.
I have checked the httpBody which definitely contains the data. I just can't figure out what I'm doing wrong here. Here is my code:
let json : [Dictionary<String,Any>] = [["label" : "Misc", "ignored": true], ["label" : "Cash", "ignored": false]]
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.setValue("application/json", forHTTPHeaderField: "Accept")
request.httpBody = try? JSONSerialization.data(withJSONObject: json)
let task = URLSession.shared.dataTask(with: request) { data, response, error in
if let response = response {
print(response)
}
}
task.resume()
Try using
URLSession(configuration: URLSessionConfiguration.default)
instead of
URLSession.shared
I ran into the same problem and this worked for me.

Opening an url in the background with swift 3?

I want to open an url in the background to update my database with information,
but it should not open safari because customer shouldn't be able to see the php link.
would be glad for any help,
i just need help to open the URL in the background
I believe what you're looking for is an HTTP request. This is what browsers do to get content from a webpage. There are many ways to do an HTTP request to a url in iOS. One such way is with the URLSession class.
let url = URL(string: "http://www.google.com/") //Or your URL
var request = URLRequest(url: url!)
request.httpMethod = "POST"
request.httpBody = "Data to send to your backend".data(using: .utf8)!
let task = URLSession.shared.dataTask(with: request) { data, response, error in
if error != nil {
//There was an error
} else {
//The HTTP request was successful
print(String(data: data!, encoding: .utf8)!)
}
}
task.resume()
This will send the data in the httpBody property to your backend in a HTTP request.

Swift 3 URLSession sending empty request

I can't get the URLSession to send anything in the body of a POST request.
Here is my code:
// Set up the request
var request = URLRequest(url: URL(string: baseURL + url)!)
request.httpMethod = "POST"
let jsonData = try JSONSerialization.data(withJSONObject: values,
options: .prettyPrinted)
request.httpBody = jsonData
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
let config = URLSessionConfiguration.ephemeral
let session = URLSession(configuration: config, delegate: self, delegateQueue: OperationQueue.main)
let task = session.dataTask(with: request) { data, response, err in
if let err = err {
print(err)
}
else {
let jsondata = data!
do {
let sessionData =
try JSONSerialization.jsonObject(with: jsondata, options: .mutableLeaves)
as? Dictionary<String, String>
callback.taskComplete(response: sessionData, task: task)
}
catch {
print(error)
}
}
}
task.resume()
The server receives the request, but the body is empty and the content type header is null. I can't use the default session because I'm developing with self-signed certificates, so I need my class to be a URLSession delegate.
I'm using Swift 3, XCode 8, and iOS 10. Any help would be appreciated.
Problem solved. It was a combination of errors. If the URL doesn't have the trailing "/", Jetty sends a 302 redirect to the same URL with the slash appended. The iOS client does the redirect with a "GET," so there is nothing in the body. When I add the trailing "/", the request works fine.
I hope this answer will help someone doing iOS development. I searched Google for hours before I posted this question. I finally found the answer in a post about the Apache Java HttpClient. It has the same behavior.
Thank you for all the responses.

Making HTTP Request with header in Swift

I am trying to make an HTTP request to the Imgur API. I am trying to retrieve all images associated with the tag "cats." The url, according to the Imgur API is: https://api.imgur.com/3/gallery/t/cats
the Imgur API states the following about the authorization needed to make get requests:
For public read-only and anonymous resources, such as getting image
info, looking up user comments, etc. all you need to do is send an
authorization header with your client_id in your requests. This also
works if you'd like to upload images anonymously (without the image
being tied to an account), or if you'd like to create an anonymous
album. This lets us know which application is accessing the API.
Authorization: Client-ID YOUR_CLIENT_ID
I've looked at the following questions and tried things suggested there, but none of them have helped.
JSON NSURLRequest with credentials
Swift GET request with parameters
How to make a Http get and set httpHeader in Swift?
My current code is this:
let string = "https://api.imgur.com/3/gallery/t/cats"
let url = NSURL(string: string)
let request = NSMutableURLRequest(URL: url!)
request.setValue("clientIDhere", forHTTPHeaderField: "Authorization")
//request.addValue("clientIDhere", forHTTPHeaderField: "Authorization")
request.HTTPMethod = "GET"
let session = NSURLSession.sharedSession()
let tache = session.dataTaskWithRequest(request) { (data, response, error) -> Void in
if let antwort = response as? NSHTTPURLResponse {
let code = antwort.statusCode
print(code)
}
}
tache.resume()
But I continually get a status code of 403, meaning authorization is required. What am I doing wrong?
I think you need to prepend Client-ID string to your actual client ID as for the header value:
request.setValue("Client-ID <your_client_id>", forHTTPHeaderField: "Authorization")
Updated for swift 4 :
func fetchPhotoRequest(YOUR_CLIENT_ID: String) {
let string = "https://photoslibrary.googleapis.com/v1/albums"
let url = NSURL(string: string)
let request = NSMutableURLRequest(url: url! as URL)
request.setValue(YOUR_CLIENT_ID, forHTTPHeaderField: "Authorization") //**
request.httpMethod = "GET"
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
let session = URLSession.shared
let mData = session.dataTask(with: request as URLRequest) { (data, response, error) -> Void in
if let res = response as? HTTPURLResponse {
print("res: \(String(describing: res))")
print("Response: \(String(describing: response))")
}else{
print("Error: \(String(describing: error))")
}
}
mData.resume()
}

Resources