HTTP Request with Body using PATCH in Swift - ios

I'm trying to send a Patch request with a serialized JSON Body.
For some reason the server is not able to receive the body properly. I have a feeling that there seems to be a problem with the PATCH method in combination with the http request body.
let sessionConfig = NSURLSessionConfiguration.defaultSessionConfiguration()
let session = NSURLSession(configuration: sessionConfig, delegate: nil, delegateQueue: nil)
var URL = B2MFetcher.urlForBooking(event.unique, bookingID: booking.unique)
let request = NSMutableURLRequest(URL: URL)
request.HTTPMethod = "PATCH"
// Headers
println(token)
request.addValue(token, forHTTPHeaderField: "Authorization")
request.addValue("gzip, identity", forHTTPHeaderField: "Accept-Encoding")
// JSON Body
let bodyObject = [
"op": "cancel"
]
var jsonError: NSError?
request.HTTPBody = NSJSONSerialization.dataWithJSONObject(bodyObject, options: nil, error: &jsonError)
/* Start a new Task */
let task = session.dataTaskWithRequest(request, completionHandler: { (data : NSData!, response : NSURLResponse!, error : NSError!) -> Void in
completion(data: data, response:response , error: error)
})
task.resume()

You could try to add a Content-Type header to the request:
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
or use one of the other JSON Content-Type formats described here.
I tested it with an ExpressJS server and without the Content-Type header the server got an empty body, but with a Content-Type header it worked well.

in swift 3/4 :
let request = NSMutableURLRequest(url: NSURL(string: "http://XXX/xx/xxx/xx")! as URL)
request.httpMethod = "PATCH"
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
do{
let json: [String: Any] = ["status": "test"]
let jsonData = try? JSONSerialization.data(withJSONObject: json)
request.httpBody = jsonData
print("jsonData: ", String(data: request.httpBody!, encoding: .utf8) ?? "no body data")
} catch {
print("ERROR")
}
let task = URLSession.shared.dataTask(with: request as URLRequest) {
data, response, error in
if error != nil {
print("error=\(error)")
completion(false)
return
}
let responseString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
print("responseString = \(responseString)")
completion(true)
return
}
task.resume()

Simple Way to use patch without using HTTPBody
If you want to just use patch, you just need to change the value of the name of a specific user then it will be like:
let myurl = URL(string: "https://gorest.co.in/public-api/users/"+"\(id)?"+"name=abc")!
var request = URLRequest(url:myurl)
request.addValue("Bearer yourAuthorizationToken",forHTTPHeaderField:"Authorization")
request.httpMethod = "PATCH"
let dataTask = URLSession.shared.dataTask(with: request)
dataTask.resume()
Note: here "id" will be userId

Related

Making a url request session returns empty while postman returns data

I'm trying to make an API call here using a post method, however I keep getting
[[boringssl] boringssl_metrics_log_metric_block_invoke(144)]
and the data returned is an empty object {"finalResults":[]}.
Tested the API using postman and the data returns safely.
This is my code:
var dict = Dictionary<String, String>()
dict = [
"queryText": query,
"lat": "31.206865038834433",
"long": "29.965068562105422",
"pageToken": "",
]
let url:URL = URL(string: apiEndPointURLString)!
let session = URLSession.shared
var postData = NSData()
do{
postData = try JSONSerialization.data(withJSONObject: dict, options: JSONSerialization.WritingOptions.prettyPrinted) as NSData
}catch {
print("error serializing.......\n\n\n\n")
}
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("\(postData.length)", forHTTPHeaderField: "Content-Length")
request.setValue("text/html", forHTTPHeaderField: "Content-Type")
request.setValue("json/application", forHTTPHeaderField: "Accept")
request.httpBody = postData as Data
let task = session.dataTask(with: request as URLRequest) {
(
data, response, error) in
guard let data = data, let _:URLResponse = response, error == nil else {
print("error")
return
}
let dataString = String(data: data, encoding: String.Encoding.utf8)
print(dataString ?? "no data")
}
task.resume()

how to make post request with row http body using swift as postman request test?

request.httpMethod = "POST"
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
let httpbody = object.data(using: String.Encoding.utf8)
request.httpBody = httpbody
You can directly generate a code from postman itself. Also, for your reference, you can call post request with row body as given below.
let headers = [
"content-type": "application/json",
"cache-control": "no-cache"
]
let parameters = ["order": ["line_items": [
["variant_id": 18055889387589,
"quantity": 1]
]]] as [String : Any]
let postData = try? JSONSerialization.data(withJSONObject: parameters, options: [])
if let data = postData {
let request = NSMutableURLRequest(url: NSURL(string: "http://")! as URL,
cachePolicy: .useProtocolCachePolicy,
timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = data as Data
let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
if (error != nil) {
print(error?.localizedDescription ?? "")
} else {
let httpResponse = response as? HTTPURLResponse
print(httpResponse?.statusCode ?? 0)
let reponseData = String(data: data!, encoding: String.Encoding.utf8)
print("responseData: \(reponseData ?? "Blank Data")")
}
})
dataTask.resume()
}
Let me know if you have any query.
Thanks.

Receive POST request from Swift in Node.js

I am trying to receive and process a POST request being sent from my iOS app to my Node.js web server. The server responds with HTTP Error 502 whenever I try to send this POST request. Could you please look at my code below and see what is wrong with it? Thank you!
Node.js Code
app.post('/applogin', function(req, res) {
var parsedBody = JSON.parse(req.body);
console.log(parsedBody)
});
Swift Code (POST function)
func httpPost(jsonData: Data) {
if !jsonData.isEmpty {
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.httpBody = jsonData
URLSession.shared.getAllTasks { (openTasks: [URLSessionTask]) in
NSLog("open tasks: \(openTasks)")
}
let task = URLSession.shared.dataTask(with: request, completionHandler: { (responseData: Data?, response: URLResponse?, error: Error?) in
NSLog("\(response)")
})
task.resume()
}
}
Swift Code (sending of the POST request)
#IBAction func onClick(_ sender: Any) {
let username = Username.text
let password = Password.text
var dataString = "username: \(username), password: \(password)"
let data = dataString.data(using: .utf8)
httpPost(jsonData: data!)
}
Thanks in advance!
You have to send a json instead dataString, and you have to set the "Content Type" header with value "application/json"
Swift 2
let request = NSMutableURLRequest(URL: requestUrl)
request.HTTPMethod = "POST"
let params = ["username" : username, "password" : password] as Dictionary<String, AnyObject>
request.HTTPBody = NSJSONSerialization.dataWithJSONObject(params, options:NSJSONWritingOptions.PrettyPrinted)
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
Many answers they don't mention that we need to set header for the request from Swift side before sending to the backend otherwise it'll be a string in a wrong format that we can't use JSON.parse, here's what I firgured out (NOTE the IMPORTANT line):
let json = [
"email": emailTextField.text
]
let jsonData = try! JSONSerialization.data(withJSONObject: json)
let url = URL(string: BASE_URL + "/auth/register")!
var request = URLRequest(url: url)
request.httpMethod = "POST"
// insert json data to the request
request.httpBody = jsonData
//IMPORTANT
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 data = data, error == nil else {
print(error?.localizedDescription ?? "No data")
return
}
let responseJSON = try? JSONSerialization.jsonObject(with: data, options: [])
if let responseJSON = responseJSON as? [String: Any] {
print(responseJSON)
}
}
task.resume()
And in your NodeJS with Express just call req.body and you're done
Try this:
app.post('/applogin', function(req, res) {
var parsedBody = JSON.parse(req.body);
console.log(parsedBody)
res.send("Request received")
});

Access Magento Rest API in iOS - swift 3.0

I want to access the magenta REST API in my iOS application.
Following is my code to access the API:
func getCustomerTokenusingURLSEssion(){
let url = URL(string: "HTTPURL")!
var urlRequest = URLRequest(
url: url,
cachePolicy: .reloadIgnoringLocalAndRemoteCacheData,
timeoutInterval: 10.0 * 1000)
urlRequest.httpMethod = "POST"
urlRequest.addValue("application/json", forHTTPHeaderField: "Accept")
let json1: [String: Any] = [
"username": "xyz#gmail.com",
"password":"xyz12345"]
let jsonData = try? JSONSerialization.data(withJSONObject: json1, options: .prettyPrinted)
urlRequest.httpBody = jsonData
let config = URLSessionConfiguration.default
let urlsession = URLSession(configuration: config)
let task = urlsession.dataTask(with: urlRequest){ (data, response, error) -> Void in
print("response from server: \(response)")
guard error == nil else {
print("Error while fetching remote rooms: \(error)")
return
}
guard let data = data,
let json = try? JSONSerialization.jsonObject(with: data) as? [String: Any] else {
print("Nil data received from fetchAllRooms service ")
return
}
print("JSON \(json)")
}
task.resume()
}
But I'm getting error message form the server as follow:
["message": Server cannot understand Content-Type HTTP header media type application/x-www-form-urlencoded]
Please help!
Thanks!
Here's working example of token-based authentication from iOS to magento2 using swift:
func restApiAuthorize(completionBlock: #escaping (String) -> Void) {
// Prepare json data
let json: [String: Any] = ["username": “yourusername”,
"password": “yourpassowrd”]
let jsonData = try? JSONSerialization.data(withJSONObject: json)
// Create post request
let url = URL(string: "http://yourmagentodomain.com/index.php/rest/V1/integration/customer/token")!
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("\(jsonData!.count)", forHTTPHeaderField: "Content-Length")
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
// Insert json data to the request
request.httpBody = jsonData
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data, error == nil else {
print(error?.localizedDescription ?? "No data")
return
}
// 1: Check HTTP Response for successful GET request
guard let httpResponse = response as? HTTPURLResponse
else {
print("error: not a valid http response")
return
}
print(httpResponse.statusCode)
switch (httpResponse.statusCode)
{
case 200:
let responseData = String(data: data, encoding: String.Encoding.utf8)!
print ("responseData: \(responseData)")
completionBlock(responseData)
default:
print("POST request got response \(httpResponse.statusCode)")
}
}
task.resume()
}
And usage is like that:
restApiAuthorize() { (output) in
// token data, I found it important to remove quotes otherwise token contains extra quotes in the end and beginning of string
let userToken = output.replacingOccurrences(of: "\"", with: "")
print ("userToken \(userToken)")
}
you can then write your userToken to userDefaults and make feature api calls.
Best Guest you forgot to set your Content-Type, so add this:
urlRequest.addValue("application/json", forHTTPHeaderField: "Content-Type")

How to POST request in Swift

I have this API http://my-api.mydoctorfinder.com/
that will return a bool value depending on the email and password you have entered.
My problem is it will always return false despite using the correct email and password.
I was thinking that I might have not sent the right parameter since I created a dictionary containing the email and password. Then passed it on NSJSONSerialization.dataWithJSONObject method
By the way, I was using SwiftyJson.
This is my code
//creates a dictionary and calls the PostRequest method
func attemptLogIn( email: String, password: String) {
let route = loggerURL
let body: [String:String] = ["email":email, "password":password]
makeHTTPPostRequest(route, body: body)
}
//performs post request
private func makeHTTPPostRequest(path: String, body: [String: AnyObject]) {
let request = NSMutableURLRequest(URL: NSURL(string: path)!)
// Set the method to POST
request.HTTPMethod = "POST"
do {
// Set the POST body for the request
let jsonBody = try NSJSONSerialization.dataWithJSONObject(body, options: .PrettyPrinted)
request.HTTPBody = jsonBody
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithRequest(request, completionHandler: {data, response, error -> Void in
if let jsonData = data {
let json:JSON = JSON(data: jsonData)
//onCompletion(json, nil)
print("The Response: ")
print(json)
} else {
//onCompletion(nil, error)
print("The Response: ")
print("Hello")
}
})
task.resume()
} catch {
// Create your personal error
//onCompletion(nil, nil)
}
}
The response is simply a true or false i.e. its not a json object.
So i would suggest don't use Swifty son instead use Alamofire.
Following code should work for you:-
let myParameters = [
"email": "your email id",
"password": "your password"]
Alamofire.request(.POST, "http://my-api.mydoctorfinder.com/ ", parameters: myParameters)
.response { request, response, data, error in
print(request)
print(response)
if(response == true)
{
// do your thing
}
print(error)
}
Note: There might be a need to typecast response to bool
Also following is the screenshot of the link you gave, it returns true(and not a json object) [After registration, i tried to login with same credentials]
Try to create JSON object using NSJSONSerialization in this way:
request.HTTPBody = try! NSJSONSerialization.dataWithJSONObject(body, options: [])
I assume that problem is in .PrettyPrinted constant.
Edit:
Also try adding correct content-type:
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
Here is the swift post request to get data :
func retriveTextDataByPost(requestURL:String, params: NSDictionary, handler:((dict:NSDictionary?) -> Void)) {
let configuration = NSURLSessionConfiguration.defaultSessionConfiguration()
let session = NSURLSession(configuration: configuration, delegate: self, delegateQueue: nil)
let url = NSURL(string: requestURL)
let request = NSMutableURLRequest(URL: url!, cachePolicy: NSURLRequestCachePolicy.UseProtocolCachePolicy, timeoutInterval: 60)
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
request.HTTPMethod = "POST"
do {
let postData = try NSJSONSerialization.dataWithJSONObject(params, options:NSJSONWritingOptions.PrettyPrinted)
request.HTTPBody = postData
let postDataTask = session.dataTaskWithRequest(request) { (data:NSData?, response:NSURLResponse?, error:NSError?) -> Void in
if data != nil {
do {
let dictResult:NSDictionary = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) as! NSDictionary
handler(dict: dictResult)
} catch { }
}
}
postDataTask.resume()
} catch { }
}
Check your keys for email and password with required input for APIs
Check your login URL

Resources