Put request IOS - ios

I try to update a object in the database trough a API call. I do this action with a PUT request. A Post request was already made and is working fine. I thought it is just copy paste...
The API part works fine because if I execute the following curl command than it updates the row I wanted in the database
$ curl -H 'Accept: application/json' -i -X PUT -d 'UserLogin=Ub0D&EndDate=2014-01-17 00:00:00.0000000&Sport=Fietsen&Distance=1000&Duration=10&Achieved=true&DateCreated=2015-05-09 12:01:00.000000' http://localhost:8089/api/goal/ub0d -k -u ub0d:test123
But now the part in swift gives me a bad request error (400)...
This is my code
var url : NSURL
url = NSURL(string: _apiUrl + connectToApi(apiCall) + String("\(AccountRepository.Instance.getCurrentUserName())"))!
let request = NSMutableURLRequest(URL: url)
if postString != nil {
let postData : NSData = ("UserLogin=Ub0D&EndDate=2014-01-1700:00:00.0000000&Sport=Fietsen&Distance=1000&Duration=10&Achieved=true&DateCreated=2014-01-1700:00:00.0000000").dataUsingEncoding(NSUTF8StringEncoding)!
// create the request
request.HTTPMethod = "PUT"
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "content-type")
request.setValue("application/json", forHTTPHeaderField: "Content-type")
request.setValue("application/json", forHTTPHeaderField: "Accept")
request.HTTPBody = postData
}
var connection: NSURLConnection = NSURLConnection(request: request, delegate: self, startImmediately: true)!
I'm really stuck on it:(

You request can't have two different content types at the same time:
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "content-type")
request.setValue("application/json", forHTTPHeaderField: "Content-type")
The data you are sending are obviously not JSON, so I guess you want only
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "content-type")
and remove the "application/json" line.
There is also a difference between your date formats:
CURL
EndDate=2014-01-17 00:00:00.0000000
Swift
EndDate=2014-01-1700:00:00.0000000
Note the missing space between date and time, probably should be URL encoded (+):
EndDate=2014-01-17+00:00:00.0000000
In general, most REST APIs send error messages in response body, so it is always good to log the response for failed requests.

Related

Swift getting error while upload base64 to server?

My scenario, I am trying to upload the user camera and photolibrary captured image to my server. Here, Already we are sending few parameters like (name, phone number, etc…) within this we are added photo parameter and sending base64 image data to the server. Now, while sending the base64 strings to the server I am getting below error.
My Error
2019-03-08 17:49:52.872545+0530 myapp[441:40026] [BoringSSL]
nw_protocol_boringssl_error(1584) [C3.1:2][0x12dfd9e80] Lower protocol
stack error: 54 2019-03-08 17:49:52.873175+0530 myapp[441:40026] TIC
Read Status [3:0x280be5140]: 1:54 2019-03-08 17:49:52.877753+0530
myapp[441:40026] Task .<4> HTTP
load failed (error code: -1005 [4:-4]) 2019-03-08 17:49:52.878073+0530
myapp[441:40125] Task .<4>
finished with error - code: -1005
I am using below code for JSON
apiPath = “https://.........com?country=\(get_countryID ?? "unknown")&last_update_date=\(today_string)&device_id=\(deviceID)&app_type=1&location=\(get_latlong)&photo=\(get_photobase64)”
if let encodeString = apiPath.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed),
let url = URL(string: encodeString) {
let session = URLSession.shared
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
request.addValue(access_key, forHTTPHeaderField: "access-key")
request.addValue(auth_token!, forHTTPHeaderField: "auth-token")
request.timeoutInterval = 10
I gave already Allow Arbitrary Loads = YES.

Swift 3 - Rest Api HTTP Header Values are not being sent

I'm trying to build an app with Swift, which makes a REST API call with an authorization header. The code looks like this:
var request = URLRequest(url: url!)
request.httpMethod = "GET"
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
request.addValue("username:password", forHTTPHeaderField: "Authorization")
request.addValue("de", forHTTPHeaderField: "Content-Language")
URLSession.shared.dataTask(with: request) { (data, response, error) in
...
...
My problem is that the HTTP Header values are somehow not being sent. I verified that the requests values are being set by printing out request.allHTTPHeaderFields, but the response from the server still holds all the default values for the headers. This is not only for the Authorization header but also for any other header I try to change.
It would be great if someone can find the mistake... I mean, it is a very simple piece of code, so I'm really confused to where it went wrong.

"HTTP Status 400 - Bad Request - The request sent by the client was syntactically incorrect"?

I've done a http request with post parameters so many times, and I have now so many of them working just fine, I don't know why this one is not
this is the code
let url = NSURL(string: "bla bla lba")
let request = NSMutableURLRequest(URL: url)
let body = "id=\(requestClient!.id!)"
print("body = \(body)")
request.HTTPBody = body.dataUsingEncoding(NSASCIIStringEncoding)
request.HTTPMethod = "POST"
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "content-type")
let session = NSURLSession.sharedSession()
let task1 = session.dataTaskWithRequest(request, completionHandler: {(data, response, error) in
the server expects a form parameter named id and its value is long
when I print the id from swift (as you can see the code), I get this
id=1453045943881.0
and i get this error
HTTP Status 400 - Bad Request - The request sent by the client was syntactically incorrect.
sounds like the server said the request is not correct, but where is the wrong?
this is the server
#Path("/checkForResponses")
#POST
public Response checkForResponeses (#FormParam("id") long id) {

How to set HTTPBody?

In Swift I'm trying to make a post request (using the NSURLSession) to sign in a user to a WebAPI web services.
The Url is www.myurltest.com/Token and I must pass the following string as POST body:
grant_type=password&username=MyUsername&password=MyPassword.
So in Swift I've make:
let session = NSURLSession.sharedSession();
let url = NSURL(string:"www.myurltest.com/Token");
let request = NSMutableURLRequest(URL: url!)
request.setValue("application/x-www-form-urlencoded; charset=utf-8", forHTTPHeaderField: "Content-Type")
request.HTTPMethod = "POST"
Now I want to set the POST body (that is a string) but I don't know how:
request.HTTPBody = ?????
Thanks.
You're almost there, you just need to turn the string into an NSData object. If your string is in a variable named body, your code will look like request.HTTPBody = body.dataUsingEncoding(NSUTF8StringEncoding)

what's the equivalent of this curl request in swift

I've tried lots of different things to recreate this curl request, and I'm going insane. If someone could help, I'd be very much appreciative.
curl -H "Content-Type: application/json" -X POST --data '[{"a": 4, "b": 5, "c": 6}]' \ -u username:password \ https://www.mywebsite.com
My latest attempt is:
let loginString = NSString(format: "%#:%#", username!, password!)
let loginData: NSData = loginString.dataUsingEncoding(NSUTF8StringEncoding)!
let base64LoginString = loginData.base64EncodedStringWithOptions(nil)
var url: NSURL = NSURL(string: "www.mywebsite.com")!
var request: NSMutableURLRequest = NSMutableURLRequest(URL: url)
request.setValue("Basic \(base64LoginString)", forHTTPHeaderField: "Authorization")
request.addValue("text/plain; charset=UTF-8", forHTTPHeaderField: "Content-Type")
request.HTTPMethod = "POST"
let bodyData = JSON(data!).rawString(encoding: NSUTF8StringEncoding, options: NSJSONWritingOptions.allZeros)
request.HTTPBody = bodyData?.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue()) {(response, data, error) in
if let tabBarVC : TabBarController = self.tabBarController as? TabBarController {
println(NSString(data: data, encoding: NSUTF8StringEncoding))
}
}
In this example, data is a dictionary ([String:String]) and JSON is form SwiftyJSON.
The above sends NSData to the server, which is encoded and the server doesn't like. The request is getting through, but the server can't read the data right. What do I need to do to exactly replicate the curl request above? I'm stuck!
Updated to reflect good responses below.
I did attempt to use application/json for content-type, but this returns the message:
{"status": "Internal error JSON uploads must be formatted as an array of objects", "code": 400, "version": "v1"}
It seems like progress if I use text/plain (as above) I get:
{"status": "Column a is missing", "code": 400, "version": "v1"}
Which I can't seem to figure out.
A couple of thoughts:
If nothing else, the line that says:
request.addValue("text/plain; charset=UTF-8", forHTTPHeaderField: "Content-Type")
Should be:
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
Your curl clearly states that the content type header was supposed to be JSON, so I'd set that accordingly.
Also, the line that says:
request.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Accept-encoding")
That's clearly not correct, either. I think you meant Accept not Accept-encoding, plus the server is undoubtedly not responding with a x-www-form-urlencoded response, anyway.
I would simply remove that line.
Your URL is missing the scheme (the http://), but I assume that was removed when editing your question, because I don't think it would work without that, but you assured us that the server did receive the request.
I'd suggest you consider a tool like Charles. Watch the request from curl and then again from your code. Compare and contrast and identify how they differ. Using this, you should be able to diagnose precisely what's going on and where the discrepancy rests.
You say:
The request is getting through, but the server can't read the data right.
If the problem persists, you should share with us how you know the request is getting through and what you mean by "can't read the data right."

Resources