I am trying to post data suing POST request, but whenever i am posting data I am getting Bad Request error.
Please check this code and if there any issue please let me know,
func callDataCall()
{
let requestURL: NSURL = NSURL(string: "REQUEST_URL")!
//convert MID dict to jsondata
let NewJSONData = try! JSONSerialization.data(withJSONObject: ["Disease_request":["Mid":self.MedicationID]], options: [])
// Convert jsondata to string
let NewJSONDataString = NSString(data:NewJSONData, encoding:String.Encoding.utf8.rawValue) as! String
print("Created Dictionary is : \(NewJSONDataString)")
let urlRequest = NSMutableURLRequest(url: requestURL as URL)
// set up the session
urlRequest.httpMethod = "POST"
urlRequest.httpBody = NewJSONDataString.data(using: String.Encoding.utf8)
let task = URLSession.shared.dataTask(with: urlRequest as URLRequest)
{
data, response, error in
let httpResponse = response as! HTTPURLResponse
let statusCode = httpResponse.statusCode
print("status code is :\(httpResponse)")
if (statusCode == 200 || statusCode == 201)
{
do
{
let json = try JSONSerialization.jsonObject(with: data!, options: []) as? [String: AnyObject]
if let content = json?["Disease"] as? [[String: AnyObject]]
{
for i in 0..<content.count
{
self.medicationContent.append(content[i] as AnyObject)
}
DispatchQueue.main.async(execute: {
self.tableview_Medication.reloadData()
})
}
}
catch
{
print("Error with Json: \(error)")
}
self.stopIndicator()
}
}
task.resume()
}
Response is :
<NSHTTPURLResponse: 0x608000231e40> { URL: "REQUEST_URL" } { status code: 400, headers {
"Cache-Control" = "no-cache";
"Content-Length" = 46;
"Content-Type" = "application/json; charset=utf-8";
Date = "Wed, 30 Nov 2016 10:38:24 GMT";
Expires = "-1";
Pragma = "no-cache";
Server = "Microsoft-IIS/8.5";
"X-AspNet-Version" = "4.0.30319";
"X-Powered-By" = "ASP.NET";
"X-Powered-By-Plesk" = PleskWin;
} }
I am using the same logic for Objective C, its working fine for me.
Got the solution !!
The Swift code is fine, i need to add one more line after httpMethod
So now the code as like this
urlRequest.httpMethod = "POST"
urlRequest.setValue("application/json", forHTTPHeaderField: "Content-Type")
Related
ı try to send string request but its not work
var request = URLRequest(url: url)
request.httpMethod = "POST"
let parameters = "{\"Language\": \"tr\",\"ProcessType\": 1,\"Username\": \"\(self.mailTextField.text ?? "")\",\"Password\": \"\(self.passwordTextField.text ?? "")\"}"
print(parameters)
let enUrlParams = try! parameters.aesEncrypt(key: LoginConstants.xApiKey, iv: LoginConstants.IV)
print(enUrlParams)
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.setValue("*/*", forHTTPHeaderField: "Accept")
request.httpBody = enUrlParams.data(using: .utf8)
Output:
{"Language": "tr","ProcessType": 1,"Username": "","Password": ""}
l+Au1MhqAlHr+wDR9UmdjN4IL5XHVnwMJx3rHF/P1MT+aO5Q5YF25f5OJRwDVzXEWu47ocqMxcUqw1onYBya9VCEvqjNQ0FpNCxtPp9fh+Y=
Optional(108 bytes)
statusCode should be 200, but is 500
response = Optional(<NSHTTPURLResponse: 0x600000e36e00> { URL: "my url" } { Status Code: 500, Headers {
Date = (
"Wed, 14 Sep 2022 11:54:35 GMT"
);
Server = (
"Microsoft-IIS/10.0"
);
"Transfer-Encoding" = (
Identity
);
"X-Powered-By" = (
"ASP.NET"
);
} })
responseString = Optional("")
If you are getting 500 as HTTP Response Code, then you need to check with the API Team, as 500 is Server Not Available.
If, Status Code lies in 4xx, then you need to bother about code, For 5xx you Server /API is not responding to your request.
I solved problem let stringRequest = ""(enUrlParams)"" this part solved my problem
let url = URL(string: MemberUrl)!
var request = URLRequest(url: url)
request.httpMethod = "POST"
let parameters = "{\"Language\": \"tr\",\"ProcessType\": 1,\"Username\": \"\(self.mailTextField.text ?? "")\",\"Password\": \"\(self.passwordTextField.text ?? "")\"}"
print(parameters)
let enUrlParams = try! parameters.aesEncrypt(key: LoginConstants.xApiKey, iv: LoginConstants.IV)
print(enUrlParams)
let stringRequest = "\"\(enUrlParams)\""
print(stringRequest)
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpBody = stringRequest.data(using: String.Encoding.utf8)
let task = URLSession.shared.dataTask(with: request as URLRequest, completionHandler: { data, response, error in
guard let data = data, error == nil else {
print("error=\(String(describing: error))")
return
}
if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 {
print("statusCode should be 200, but is \(httpStatus.statusCode)")
print("response = \(String(describing: response))")
}
if let responseString = String(data: data, encoding: .utf8) {
print("responseString = \(String(describing: responseString))")
self.userDC = responseString ?? ""
self.userDC = try! self.aesDecrypt(key: LoginConstants.xApiKey, iv: LoginConstants.IV)
print(self.userDC)
self.login()
}
})
task.resume()
I try to display Firebase Cloud Messaging's notification in background on my iPhone but it doesn't work when I send this notification with Swift.
I send a FCM to my iPhone with a HTTP request in Postman and that's work fine: my iPhone display the notification correctly in background.
When I make the same HTTP request with Swift, the Firebase's response is fine but my iPhone don't display nothing.
There is the request and the response in Postman :
Postman's screenshot
There is the same request in a Swift Playground :
import Foundation
let key = "key=<my-server-key>"
let singleMessageUrl = "https://fcm.googleapis.com/fcm/send"
func sendSingleMessage() {
let params: [String: Any] = [
"to": "<my-device-token>",
"notificiation": [
"title": "Push from my playground",
"body": "Push from my playground !"
],
]
guard let bodyNotif = try? JSONSerialization.data(withJSONObject: params, options: []) else {
print("BAD NOTIF")
return
}
guard let json = try? JSONSerialization.jsonObject(with: bodyNotif, options: []) as? [String: Any] else {
print("BAD JSON")
return
}
print("PARAMS REQUEST:\n", params)
print("---------------------------")
print("JSON REQUEST:\n", json)
print("---------------------------")
guard let url = URL(string: singleMessageUrl) else {
print("BAD URL")
return
}
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.httpBody = bodyNotif
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.setValue(key, forHTTPHeaderField: "Authorization")
URLSession.shared.dataTask(with: request) { (data, response, error) in
if let error = error {
print("ERROR", error.localizedDescription)
}
guard let response = response else { return }
print("HEADERS RESPONSE:\n", response)
print("---------------------------")
guard let data = data else { return }
guard let json = try? JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] else {
print("BAD JSON RESPONSE")
return
}
print("BODY RESPONSE:\n", json)
}.resume()
}
sendSingleMessage()
When I launch the above request, the response appears to be OK in the console :
PARAMS REQUEST:
["to": "<my-device-token>", "notificiation": ["title": "Push from my playground", "body": "Push from my playground !"]]
---------------------------
JSON REQUEST:
["to": <my-device-token>, "notificiation": {
body = "Push from my playground !";
title = "Push from my playground";
}]
---------------------------
HEADERS RESPONSE:
<NSHTTPURLResponse: 0x7fcaf544c610> { URL: https://fcm.googleapis.com/fcm/send } { Status Code: 200, Headers {
"Cache-Control" = (
"private, max-age=0"
);
"Content-Encoding" = (
gzip
);
"Content-Length" = (
138
);
"Content-Type" = (
"application/json; charset=UTF-8"
);
Date = (
"Sun, 05 Jan 2020 09:47:15 GMT"
);
Expires = (
"Sun, 05 Jan 2020 09:47:15 GMT"
);
Server = (
GSE
);
"alt-svc" = (
"quic=\":443\"; ma=2592000; v=\"46,43\",h3-Q050=\":443\"; ma=2592000,h3-Q049=\":443\"; ma=2592000,h3-Q048=\":443\"; ma=2592000,h3-Q046=\":443\"; ma=2592000,h3-Q043=\":443\"; ma=2592000"
);
"x-content-type-options" = (
nosniff
);
"x-frame-options" = (
SAMEORIGIN
);
"x-xss-protection" = (
"1; mode=block"
);
} }
---------------------------
BODY RESPONSE:
["multicast_id": <the-multicast_id-send-by-FCM>, "results": <__NSSingleObjectArrayI 0x7ff55bd46aa0>(
{
"message_id" = "<the-message_id-send-by-FCM>";
}
)
, "success": 1, "failure": 0, "canonical_ids": 0]
But unfortunately my iPhone receive nothing whith this Swift's request while it receive correctly the notification send whith the Postman's request.
I've checked this code on my app - it works 100%. The code itself contains a force unwrapping and is copied from the Postman, so it will require optimization in the future, but you can quickly check it if you add the device token and the server key. Also I've tested your code and found one issue - you should change "notificiation" to "notification". Hope this help you.
class ViewController: UIViewController {
var semaphore = DispatchSemaphore (value: 0)
var request = URLRequest(url: URL(string: "https://fcm.googleapis.com/fcm/send")!,timeoutInterval: Double.infinity)
override func viewDidLoad() {
super.viewDidLoad()
sendSingleMessage()
}
func sendSingleMessage() {
let parameters = "{\n \"to\" : \"<my-device-token>\", \n\n \"notification\": {\n \"body\": \"From Swift code message\"\n }\n\n }"
let postData = parameters.data(using: .utf8)
request.addValue("key=<my-server-key>", forHTTPHeaderField: "Authorization")
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpMethod = "POST"
request.httpBody = postData
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data else {
print(String(describing: error))
return
}
print(String(data: data, encoding: .utf8)!)
self.semaphore.signal()
}
task.resume()
semaphore.wait()
}
}
I've setup the api post request which is working fine with postman, however in my swift code it doesn't send the params with the request.
let parameters = ["spotId" : spotId,
"voteruptime" : currentDate,
"voterupid" : userId] as [String : Any]
guard let url = URL(string: "http://example.com:3000/upvote") else { return }
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.addValue("Application/json", forHTTPHeaderField: "Content-Type")
guard let httpBody = try? JSONSerialization.data(withJSONObject: parameters, options: []) else { return }
request.httpBody = httpBody
print(request.httpBody)
let session = URLSession.shared
session.dataTask(with: request) { (data, response, error) in
if let response = response {
print(response)
}
if let data = data {
do {
let json = try JSONSerialization.jsonObject(with: data, options: [])
print(json)
} catch {
print(error)
}
}
}.resume()
I got a response
<NSHTTPURLResponse: 0x618000a26560> { URL: http://example.com:3000/upvote } { status code: 200, headers {
Connection = "keep-alive";
"Content-Length" = 28;
"Content-Type" = "application/json; charset=utf-8";
Date = "Sat, 21 Oct 2017 03:11:46 GMT";
Etag = "W/\"1c-BWaocQVSSeKjLiaYjOC8+MGSQnc\"";
"X-Powered-By" = Express;} }
{
n = 0;
nModified = 0;
ok = 1;
}
The server code Node JS is:
app.post('/upvote', function(req, res){
Spots.update({_id: req.query.spotId},{$push:{'upvotes':{'voterupid':req.query.voterupid,'voteruptime':req.query.voteruptime}}},function( err, Spots){
console.log(req.url)
if(err){
throw err;
}
res.json(Spots);
});
});
I tried also alamofire, and it's the same issue, no params sent to the server.
I believe the issue is that req.query accesses data passed on the query string, whereas you are POSTing the data in the body of the request.
To access the body, you need to use body-parser as described in multiple answers here: How to access the request body when POSTing using Node.js and Express?
Code here
let link = "https://api.yelp.com/oauth2/token"
guard let url = URL(string: link) else { return }
// Headers
let headers = [
"content-type": "application/x-www-form-urlencoded"
]
guard let clientID = infoPlist(withKey: "YELP_API_CLIENT_ID"),
let clientSecret = infoPlist(withKey: "YELP_API_CLIENT_SECRET") else { return }
let body = "client_id=\(clientID)&client_secret=\(clientSecret)&grant_type=client_credentials"
var request = URLRequest.init(url: url)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = body.data(using: .utf8)
As far as I know this should be working. Based on everything I've read this is the proper process for authenticating with Yelp Fusion/v3.
You didn't post your entire code, but with some slight modifications your code works:
let appId = "xxx"
let appSecret = "yyy"
let link = "https://api.yelp.com/oauth2/token"
let url = URL(string: link)!
let bodyData = "client_id=\(appId)&client_secret=\(appSecret)&grant_type=client_credentials".data(using: .utf8)!
// Headers
let headers = [
"Content-Type": "application/x-www-form-urlencoded",
"Content-Length": "\(bodyData.count)"
]
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = bodyData
typealias JSON = [String:Any]
URLSession.shared.dataTask(with: request) { (data, response, error) in
guard let data = data,
let httpResponse = response as? HTTPURLResponse,
httpResponse.statusCode == 200 else {
print(error!)
return
}
if let responseJSON = try? JSONSerialization.jsonObject(with:data, options:[]),
let parsedJSON = responseJSON as? JSON {
let token = parsedJSON["access_token"]
let exipration = parsedJSON["expires_in"]
}
}.resume()
I am requesting some data by json , I am new to SWIFT for iOS so I don't get whats the problem in my code :
var URL="http://X.X.X.X.X/Api/UserManagement/getMobileUser";
var UserId=uname.text;
var pword=passwd.text;
var PostData: NSString = "{\"data\":{},\"action\":\"System\",\"method\":\"getMobileUser\",\"username\":\" mpc01\",\"password\":\"mpc01\",\"type\":\"rpc\",\"tid\":\"144\"}"
let request = NSMutableURLRequest(URL: NSURL(string: URL)!)
request.HTTPMethod = "POST"
let postString = PostData
//var st:NSData = PostData.dataUsingEncoding(NSUTF8StringEncoding)!
// request.HTTPBody = PostData.dataUsingEncoding(NSUTF8StringEncoding)
request.HTTPBody = (postString as NSString).dataUsingEncoding(NSUTF8StringEncoding)
//let data = (postString as NSString).dataUsingEncoding(NSUTF8StringEncoding)
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
data, response, error in
if error != nil {
println("error=\(error)")
return
}
println("response = \(response)")
let responseString = NSString(data: data, encoding: NSUTF8StringEncoding)
println("responseString = \(responseString)")
}
task.resume()
THE response I get is :
response = { URL: http://X.X.X.X/Api/UserManagement/getMobileUser } { status code: 500, headers {
"Cache-Control" = "no-cache";
"Content-Length" = 36;
"Content-Type" = "application/json; charset=utf-8";
Date = "Sat, 03 Jan 2015 06:11:51 GMT";
Expires = "-1";
Pragma = "no-cache";
Server = "Microsoft-IIS/7.5";
"X-AspNet-Version" = "4.0.30319";
"X-Powered-By" = "ASP.NET";
} }
responseString = Optional({"Message":"An error has occurred."})
I had a similar problem trying to POST to MailGun for some automated emails I was implementing in an app.
I was able to get this working properly with a large HTTP response. I put the full path into Keys.plist so that I can upload my code to github and broke out some of the arguments into variables so I can have them programmatically set later down the road.
// Email the FBO with desired information
// Parse our Keys.plist so we can use our path
var keys: NSDictionary?
if let path = NSBundle.mainBundle().pathForResource("Keys", ofType: "plist") {
keys = NSDictionary(contentsOfFile: path)
}
if let dict = keys {
// variablize our https path with API key, recipient and message text
let mailgunAPIPath = dict["mailgunAPIPath"] as? String
let emailRecipient = "bar#foo.com"
let emailMessage = "Testing%20email%20sender%20variables"
// Create a session and fill it with our request
let session = NSURLSession.sharedSession()
let request = NSMutableURLRequest(URL: NSURL(string: mailgunAPIPath! + "from=FBOGo%20Reservation%20%3Cscheduler#<my domain>.com%3E&to=reservations#<my domain>.com&to=\(emailRecipient)&subject=A%20New%20Reservation%21&text=\(emailMessage)")!)
// POST and report back with any errors and response codes
request.HTTPMethod = "POST"
let task = session.dataTaskWithRequest(request, 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! NSHTTPURLResponse
print("response code = \(httpResponse.statusCode)")
}
})
task.resume()
}
The Mailgun Path is in Keys.plist as a string called mailgunAPIPath with the value:
https://API:key-<my key>#api.mailgun.net/v3/<my domain>.com/messages?
Hope this helps!