Swift API call with URLSession gives 504 error - swift

I have an API call with oauth which I tested with correct authorization token in postman.I am getting proper response in postman. But when I try same thing in Swift, I get 504 error.
I have checked every params and headers properly and everything looks same as postman. Not sure why samething is working in postman and gives 504 error in swift. what could be issue?
var params = [String : String]()
params["Id"] = Id;
var headers = [String : String]()
headers["api-key"] = "XXXXXX"
headers["Authorization"] = "Bearer XXX"
do{
var request = URLRequest(url: URL(string: getURL())!)
request.allHTTPHeaderFields = headers
request.httpBody = try JSONSerialization.data(withJSONObject: params , options: [])
request.httpMethod = "GET"
let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
let httpResponse = response as! HTTPURLResponse
print(httpResponse)
}
task.resume()
}catch{
}

When using a GET request, there is no body to the request. Everything goes on the URL.
Also are you sure that in Postman you are using only those 2 headers?
See if something like this works for you:
var params: Parameters = Parameters()
params.updateValue(Id, forKey: "Id")
var components = URLComponents(string: getURL())!
components.queryItems = params.map { (key, value) in
URLQueryItem(name: key, value: value)
}
components.percentEncodedQuery = components.percentEncodedQuery?.replacingOccurrences(of: "+", with: "%2B")
let request = URLRequest(url: components.url!)
request.setValue("XXXXXX", forHTTPHeaderField: "api-key")
request.setValue("Bearer XXX", forHTTPHeaderField: "Authorization")
request.httpMethod = "GET"
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()

Related

URLSession returns HTTP 403 error page

I'm trying to run a HTTP Request in Swift, to POST 2 parameters to a URL.
But it always returns 403 error page, what's wrong?
I trying adding Content-type header, but it doesn't work.
Code:
print("ENVIAR DATOS")
let url = NSURL(string: "https://www.portaljuridico.com.co/portaljuridico/User/login")
let request = NSMutableURLRequest(url: url! as URL)
request.httpMethod = "POST"
let param = ["username" : "juan", "password" : "123"]
guard let httpBody = try? JSONSerialization.data(withJSONObject: param, options: []) else { return }
//request.addValue("application/form-data", forHTTPHeaderField: "Content-Type")
//request.setValue("application/json", forHTTPHeaderField: "Content-Type")
//request.addValue("application/json", forHTTPHeaderField: "Accept")
request.httpBody = httpBody
let task = URLSession.shared.dataTask(with: request as URLRequest) { data, response, error in
guard let data = data, error == nil else {
print("error = \(error!)")
return
}
if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 {
print("statusCode should be 200, but is \(httpStatus.statusCode)")
print("response = \(response!)")
}
let responseString = String(data: data, encoding: .utf8)
print("responseString = \(responseString!)")
}
task.resume()
Endpoint appears to be http://www.portaljuridico.com.co/portaljuridico/User/loginUser and redirects to http://www.portaljuridico.com.co/portaljuridico/Login on invalid user/password.

How to convert this to a POST call with a JSON serialized Object

I have tried Alamofire, I have tried it with all my heart. It just does not work for me. I finally got http GET working, but I need to get http POST working. Our POST API's take a Request object that has all the necessary data in it. I have requested the backend developers to provide me with a KEY-VALUE pair JSON (no embedded objects/arrays) so that I can use a Dictionary in my swift code convert that to json and send the request. All I need is now to convert the below code to POST.
My earlier questions that did not help much.
NSInvalidArgumentException Invalid type in JSON write DemographicsPojo
Swift 3.0, Alamofire 4.0 Extra argument 'method' in call
I have given up on Alamofire. I want to use Foundation classes. Simple basic and fundamental way of life :).
func callWebService(url : String) {
// Show MBProgressHUD Here
var config :URLSessionConfiguration!
var urlSession :URLSession!
config = URLSessionConfiguration.default
urlSession = URLSession(configuration: config)
// MARK:- HeaderField
let HTTPHeaderField_ContentType = "Content-Type"
// MARK:- ContentType
let ContentType_ApplicationJson = "application/json"
//MARK: HTTPMethod
let HTTPMethod_Get = "GET"
let callURL = URL.init(string: url)
var request = URLRequest.init(url: callURL!)
request.timeoutInterval = 60.0 // TimeoutInterval in Second
request.cachePolicy = URLRequest.CachePolicy.reloadIgnoringLocalCacheData
request.addValue(ContentType_ApplicationJson, forHTTPHeaderField: HTTPHeaderField_ContentType)
request.httpMethod = HTTPMethod_Get
let dataTask = urlSession.dataTask(with: request) { (data,response,error) in
if error != nil{
print("Error **")
return
}
do {
let resultJson = try JSONSerialization.jsonObject(with: data!, options: []) as? [String:AnyObject]
print("Result",resultJson!)
} catch {
print("Error -> \(error)")
}
}
dataTask.resume()
print("..In Background..")
}
Just pass JSON string and the API URL to this function. Complete code for POST.
func POST(api:String,jsonString:String,completionHandler:#escaping (_ success:Bool,_ response:String?,_ httpResponseStatusCode:Int?) -> Void) {
let url = URL(string: api)
var request: URLRequest = URLRequest(url: url!)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField:"Content-Type")
request.timeoutInterval = 60.0
//additional headers
if let token = Helper.readAccessToken() {
request.setValue("\(token)", forHTTPHeaderField: "Authorization")
}
let jsonData = jsonString.data(using: String.Encoding.utf8, allowLossyConversion: true)
request.httpBody = jsonData
let task = URLSession.shared.dataTask(with: request) {
(data: Data?, response: URLResponse?, error: Error?) -> Void in
var responseCode = 0
if let httpResponse = response as? HTTPURLResponse {
responseCode = httpResponse.statusCode
print("responseCode \(httpResponse.statusCode)")
}
if error != nil {
completionHandler(false, error?.localizedDescription,nil)
} else {
let responseString = String(data: data!, encoding: .utf8)
completionHandler(true, responseString, responseCode)
}
}
task.resume()
}

401 Forbidden when sending email with Swift and Mailgun

I have the following code but consistently get error 401 forbidden when attempting to run it:
func email() {
let session = URLSession.shared
let request = NSMutableURLRequest(url: NSURL(string: "https://api.mailgun.net/v3/{edited_out}/messages")! as URL)
request.httpMethod = "POST"
let data = "from: Swift Email <(test#test.com)>&to: [my_email_address#gmail.com,(my_email_address#gmail.com)]&subject:Hello&text:Testing_some_Mailgun_awesomness"
request.httpBody = data.data(using: String.Encoding.ascii)
request.setValue("application/x-www-form-urlencoded; charset=utf-8", forHTTPHeaderField: "Content-Type")
request.setValue("key-{edited_out}", forHTTPHeaderField: "api")
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()
}
The error is:
url = https://api.mailgun.net/v3/{edited_out}/messages
response = <NSHTTPURLResponse: 0x600000226a20> { URL: https://api.mailgun.net/v3/{edited_out}/messages } { status code: 401, headers {
Connection = "keep-alive";
"Content-Length" = 9;
"Content-Type" = "text/html; charset=utf-8";
Date = "Thu, 29 Dec 2016 21:22:46 GMT";
Server = nginx;
"Www-Authenticate" = "Basic realm=\"MG API\"";
} }
response code = 401
If I send such a request via curl with my credentials it works fine.
Any ideas?
You need to set the uesrname and the password.
Something like this:
request.setValue("Basic \(base64Credentials)", forHTTPHeaderField: "Authorization")
and base64Credentials is the :
let credentials= String(format: "%#:%#", username, password)
let base64Credentials= credentials.data(using: String.Encoding.utf8)!
Finally got it working with the following code, if it helps anyone else:
func email() {
let session = URLSession.shared
let request = NSMutableURLRequest(url: NSURL(string: "https://api.mailgun.net/v3/{edited_out}/messages")! as URL)
request.httpMethod = "POST"
let credentials = "api:key-{omitted}"
request.setValue("Basic \(credentials.toBase64())", forHTTPHeaderField: "Authorization")
let data = "from: Swift Email <(test#test.com)>&to: [my_email_address#gmail.com,(my_email_address#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()
}
extension String {
func fromBase64() -> String? {
guard let data = Data(base64Encoded: self) else {
return nil
}
return String(data: data, encoding: .utf8)
}
func toBase64() -> String {
return Data(self.utf8).base64EncodedString()
}
}
So I guess the answer from William would have worked with:
let base64Credentials = credentials.data(using: String.Encoding.utf8)!.base64EncodedString()
Instead of:
let base64Credentials = credentials.data(using: String.Encoding.utf8)!

Translating Alamofire call to URLSession

I've got a old codebase that I'm trying to migrate out of. The network calls currently use Alamofire 4.0 and I'm trying to use URLSession instead. I'm having trouble figuring out what's wrong, here's what I've been doing. I start off with the route and params that I want to post:
// route to user creation
let url = ...
let params = ["user": ["first_name": "John", "last_name": "Appleseed", "email": "john#apple.com", "password": "asdfgh"]]
Here's the old and new network calls:
// old network request
Alamofire.request(url, method: .post, parameters: newUser, encoding: JSONEncoding.default).responseJSON { response in
// ...
}
// new code
var request = URLRequest(url: url)
let jsonData = try! JSONSerialization.data(withJSONObject: params, options: .prettyPrinted)
request.httpBody = jsonData
request.httpMethod = "POST"
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data, error == nil else { return print("error=\(error)") }
if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 {
print("status code should be 200, but is \(httpStatus.statusCode)")
print("response = \(response)")
}
let responseString = String(data: data, encoding: .utf8)
print("responseString = \(responseString)")
}
task.resume()
For some reason, I'm getting a status code of 400 in my URLSession attempt. Alamofire works fine.
Any advice appreciated.
The problem is that the request isn't recognized as a JSON call. Write the following assignment after you create your URLRequest:
request.allHTTPHeaderFields = ["Content-Type": "application/json"]

http post method passing multiple json parameters with alamofire in swift 2.0

strong text this is my code to pass two parameters(jsonData and device_Secret) to httpBody for that i should get following son in response
{"success":false,"msg":"Key not created plz try again."}
but i m getting this
responseString = Optional({"success":false,"msg":"Invalid Method"})
there is a problem in parameters format, what i am doing wrong?
my code is following /////////////
let JsonData = ["method":"device_token","params":["key":"1234jhg","device_id":"eb7e630a9637b0b83557e5a62121be8cb9210afb9aa5b878f819b775cb7d42a6"]]
let device_secret = ["params":["token":"-1","device_id":"9de47fb53c67eca4","key":"-1"]]
let params = ["data":JsonData, "device_secret":device_secret] as Dictionary<String, AnyObject>
let request = NSMutableURLRequest(URL: NSURL(string: "http://dev.jobsmarket.pk/api/v1")!)
print(request)
request.HTTPMethod = "POST"
let data : NSData = NSKeyedArchiver.archivedDataWithRootObject(params)
print("NSdata of params is")
print(data)
NSJSONSerialization.isValidJSONObject(params)
print( NSJSONSerialization.isValidJSONObject(params))
// request.HTTPBody = params
request.HTTPBody = NSKeyedArchiver.archivedDataWithRootObject(params)
print("httpBody is ")
print(request.HTTPBody)
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { data, response, error in
guard error == nil && data != nil else { // check for fundamental networking error
print("error=\(error)")
return
}
if let httpStatus = response as? NSHTTPURLResponse where httpStatus.statusCode != 200 { // check for http errors
print("statusCode should be 200, but is \(httpStatus.statusCode)")
print("response = \(response)")
}
let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding)
print("responseString = \(responseString)")
}
task.resume()
/////////////////////////