Add headers in request but still have a 403 - swift

I am trying to request an API in order to get response data. I need to add to headers in the request what I have done using request.addValue(""). It works fine when I am using postman. But I don't why I got no data with Xcode. The response is 403 Forbidden
class Service {
private static let sUrl = URL(string: "https://bff-mobile-dev.XXXXX.com/demands/filter")!
static func getData() {
var request = URLRequest(url: sUrl)
request.httpMethod = "POST"
let session = URLSession(configuration: .default)
request.addValue("Accept-Version", forHTTPHeaderField: "3.0.0")
request.addValue("X-Request-Id", forHTTPHeaderField: "057BC3BD-46E1-4125-9F3B-23805CA3132F")
let task = session.dataTask(with: request) { (data, response, error) in
if let data = data, error == nil {
if let response = response as? HTTPURLResponse {
print(response)
}
}
}
task.resume()
}
}

I believe your key value pair is mixed up when you added the header fields.
request.setValue(value,forHTTPHeaderField: "HeaderFieldName")
Adding like this works.

I think that you inverted values of you header; they should be like this
request.addValue("3.0.0", forHTTPHeaderField: "Accept-Version")
request.addValue("057BC3BD-46E1-4125-9F3B-23805CA3132F", forHTTPHeaderField: "X-Request-Id")

Try something like below
var headerData:[String:String] = [:]
headerData["Accept-Version"] = "3.0.0"
headerData["X-Request-Id"] = "057BC3BD-46E1-4125-9F3B-23805CA3132F"
request.allHTTPHeaderFields = headerData

Related

How to use POST request to Firebase Firestore from swift?

I would like to use the Firestore REST API from Swift, because I am using Siri Shortcut Intents, where I am not able to use the native SDK.
What I have tried so far is to create an URLSession with "POST" httpmethod, but no luck. I have been able successfully to create document to use the form found on firestore website. But I could make successful Swift version of it.
Here is the code I have tried:
private func addTask() {
let parent = "projects/reality-kanban/databases/(default)/documents/l3VXrtTLoz11VGn60ott"
let collectionId = "A33XrtfL2ea3dG340era"
let urlString = "https://firestore.googleapis.com/v1/\(parent)/\(collectionId)"
let requestBody = DocumentBody(name: parent, fields: RequestTask(description: "test")) // it is a codable struct
let jsonData = try! JSONEncoder().encode(requestBody)
print(String(data: jsonData, encoding: .utf8)!)
let url = URL(string: urlString)!
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.httpBody = jsonData
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let httpResponse = response as? HTTPURLResponse, (200...299).contains(httpResponse.statusCode) else {
print("Invalid Response received from the server") // this is what I get
return
}
}
task.resume()
}
This is the error I get: Invalid Response received from the server (400)
Add --debug to the command you are running to corroborate if you have set the right project.

Swift: Mailgun 401 response code--No valid API key provided

So I have my send email function as seen below:
func email() {
let session = URLSession.shared
let request = NSMutableURLRequest(url: NSURL(string: "https://api.mailgun.net/v3/sandbox################################/messages")! as URL)
request.httpMethod = "POST"
let credentials = "api:key-################################-########-########"
request.setValue("Basic \(credentials.toBase64())", forHTTPHeaderField: "Authorization")
let data = "from: Swift Email <(test#test.com)>&to: [myemail#gmail.com,(myemail#gmail.com)]&subject:Hello&text:Testing_some_Mailgun_awesomness"
request.httpBody = data.data(using: String.Encoding.ascii)
let task = session.dataTask(with: request as URLRequest, completionHandler: {(data, response, error) in
if let error = error {
print(error)
}
if let response = response {
print("url = \(response.url!)")
print("response = \(response)")
let httpResponse = response as! HTTPURLResponse
print("response code = \(httpResponse.statusCode)")
}
})
task.resume()
}
So I guess either my API key is wrong or my request URL is wrong. To find my request URL, I went to https://app.mailgun.com/app/dashboard and then scrolled down to the Sending Domains section and copied that. To get my API key I went to https://app.mailgun.com/app/account/security/api_keys and just copied the Private API Key. I'm really not sure why I'm getting this invalid code--thank you in advance if you figure it out!
Side note: Not really sure if the data constant is set up right (in terms of missing or having too many parens), so if you could check that too that would be phenomenal.
I have a software called "paw" it helps forming REST API call for Xcode, curl, php, etc.
I don't know if this could help you
class MyRequestController {
func sendRequest(somevar: String, completion: #escaping (Books) -> Void) {
/* Configure session, choose between:
* defaultSessionConfiguration
* ephemeralSessionConfiguration
* backgroundSessionConfigurationWithIdentifier:
And set session-wide properties, such as: HTTPAdditionalHeaders,
HTTPCookieAcceptPolicy, requestCachePolicy or timeoutIntervalForRequest.
*/
let sessionConfig = URLSessionConfiguration.default
/* Create session, and optionally set a URLSessionDelegate. */
let session = URLSession(configuration: sessionConfig, delegate: nil, delegateQueue: nil)
/* Create the Request:
(POST https://api.mailgun.net/v3/YOUR_DOMAIN_NAME/messages)
*/
guard var URL = URL(string: "https://api.mailgun.net/v3/YOUR_DOMAIN_NAME/messages") else {return}
var request = URLRequest(url: URL)
request.httpMethod = "POST"
// Headers
request.addValue("Basic YXBpOllPVVJfQVBJX0tFWQ==", forHTTPHeaderField: "Authorization")
request.addValue("multipart/form-data; charset=utf-8; boundary=__X_PAW_BOUNDARY__", forHTTPHeaderField: "Content-Type")
// Body
let bodyString = "--__X_PAW_BOUNDARY__\r\nContent-Disposition: form-data; name=\"from\"\r\n\r\n'Excited User <mailgun#YOUR_DOMAIN_NAME>'\r\n--__X_PAW_BOUNDARY__\r\nContent-Disposition: form-data; name=\"to\"\r\n\r\nYOU#YOUR_DOMAIN_NAME\r\n--__X_PAW_BOUNDARY__\r\nContent-Disposition: form-data; name=\"to\"\r\n\r\nbar#example.com\r\n--__X_PAW_BOUNDARY__\r\nContent-Disposition: form-data; name=\"subject\"\r\n\r\n'Hello'\r\n--__X_PAW_BOUNDARY__\r\nContent-Disposition: form-data; name=\"text\"\r\n\r\n'Testing some Mailgun awesomeness!'\r\n--__X_PAW_BOUNDARY__--\r\n"
request.httpBody = bodyString.data(using: .utf8, allowLossyConversion: true)
/* Start a new Task */
let task = session.dataTask(with: request, completionHandler: { (data: Data?, response: URLResponse?, error: Error?) -> Void in
if (error == nil) {
// Success
let statusCode = (response as! HTTPURLResponse).statusCode
print("URL Session Task Succeeded: HTTP \(statusCode)")
}
else {
// Failure
print("URL Session Task Failed: %#", error!.localizedDescription);
}
})
task.resume()
session.finishTasksAndInvalidate()
}
}
**** and you CALL this function a bit like this
MyRequestController().sendRequest(somevar: "something")
take a look at https://www.youtube.com/watch?v=44APgBnapag for more details
this tutorial show how to do REST API calls with Xcode, this example it scan a barcode, send the scanned code via a function that calls the API and return infos...

How to use cURL requests with Swift URLSession

I have a request that looks like this:
curl --header "token: YOUR TOKEN HERE" --data "a=new_session" site url
I understand and can use it via Terminal but I'm trying to do it with Swift and having some issues understanding how to pass parameters and make a request.
What I've tried:
guard let url = URL(string: siteURL) else { return }
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.addValue(token, forHTTPHeaderField: "token")
request.addValue("new_session", forHTTPHeaderField: "a")
URLSession.shared.dataTask(with: request) { (data, response, error) in
guard error == nil else { print(error!.localizedDescription); return }
guard let data = data else { print("Empty data"); return }
if let str = String(data: data, encoding: .utf8) {
print(str)
}
}.resume()
And that doesn't seem to work, I'm a very new to all this networking stuff and I don't even know why we pass token after ":" and new_session after "=" so I would appreciate any help!
You're solution is almost correct. You're just incorrectly converting the --data flag from the curl request. The format of your data is form encoded because it has the format of key=value. So you just need to add the form encoded data (in this case a=new_session) to the body of your HTTP request instead of as a header. Also, make sure to set the proper content type.
It would look something like this:
func makeRequest(siteURL: String, token: String) {
guard let url = URL(string: siteURL) else { return }
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.addValue(token, forHTTPHeaderField: "token")
// These two lines are what you were missing.
request.httpBody = "a=new_session".data(using: .utf8)!
request.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
URLSession.shared.dataTask(with: request) { (data, response, error) in
// handle the request
}.resume()
}
The URLSession request and curl request should be equivalent now.

Post data using URLSession

When i try from Alamofire then it work fine but when i try to solve from URLSESSION Swift 4 then i got wrong response.
I checked in postman and it's response was right.
Parameter Description:
I have a key "data" whose value is another dictionary ["answer1":"1","answer2":"2","answer3":"3"]. Need to post this.
Wrong Reposnse = {"message = "Invalid data."; response = failure;}"
Right Reposnse = {"response":"success","message":"Data Inserted”}.
func postData()
{
let BASEURLS = "http://sebamedretail.techizer.in/babystore_api/question_data"
let parameter = ["data":["answer1":"1","answer2":"2","answer3":"3"]]
let session = URLSession.shared
var request = URLRequest.init(url: URL.init(string: BASEURLS)!)
request.httpMethod = "POST"
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
do
{
request.httpBody = try JSONSerialization.data(withJSONObject:parameter, options: [])
let task = session.dataTask(with: request, completionHandler: { (data, response, error) in
do{
let responseArr = try! JSONSerialization.jsonObject(with: data!, options: [])
}
})
task.resume()
}
catch
{}
}
Everything seems fine, maybe you should check the way you extract the JSON in your code, if it's PHP, here could be a solution: https://stackoverflow.com/a/18867369/7452015

NSURLSession parameters not recognized

Im attemping to make a HTTPRequest using NSURLSession. When I set the full url the request returns the correct data but when using parameters (NSJSONSerialization.dataWithJSONObject -> HTTPBody I get this error
error Domain=NSURLErrorDomain Code=-1005 "The network connection was lost."
is there something im doing wrong here?
let json = ["api_key": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"]
do {
let jsonData = try NSJSONSerialization.dataWithJSONObject(json, options: .PrettyPrinted)
let url = NSURL(string: "https://api.themoviedb.org/3/discover/movie")!
let request = NSMutableURLRequest(URL: url)
request.HTTPBody = jsonData
request.HTTPMethod = "GET"
request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
let task = NSURLSession.sharedSession().dataTaskWithRequest(request){ data, response, error in
if error != nil{
print("Error -> \(error)")
return
}
do {
let result = try NSJSONSerialization.JSONObjectWithData(data!, options: []) as? [String:AnyObject]
print("Result -> \(result)")
} catch {
print("Error -> \(error)")
}
}
task.resume()
} catch {
print(error)
}
}
This is not a duplicate! I looked at the suggested answer (none of them worked) before asking this question
In your case that issue can be solved by changing the request.HTTPMethod = "GET" to request.HTTPMethod = "POST"
You should not send HTTP Body in the get request, to send the data with the body you should change HTTPMethod to post
Note: Please check if this api method supports POST requests, if it don't support post you can't use it with http body/post, as per doc i only find 'get' request for the discover/movie which can be like this:
let url = NSURL(string: "http://api.themoviedb.org/3/discover/movie?api_key=YOUR_API_KEY")!
let request = NSMutableURLRequest(URL: url)
request.addValue("application/json", forHTTPHeaderField: "Accept")
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithRequest(request) { data, response, error in
if let response = response, data = data {
print(response)
print(String(data: data, encoding: NSUTF8StringEncoding))
} else {
print(error)
}
}
task.resume()
Ref: You can check more information from this url: http://docs.themoviedb.apiary.io/#reference/discover/discovermovie/get