Swift: Save responseString ID to String - ios

Sending this code with HTTP POST returns an ID, but I'm so far unable to extract the ID from responseString and save it as it's own String in my app.
I'm looking into using Alamofire, perhaps that'll make things easier but I was hoping to be able to do it using just Swift code. Any help is appreciated.
var parseError: NSError?
let date = NSDate()
let timeStamp = date.timeIntervalSince1970
var request = NSMutableURLRequest(URL: NSURL(string: URL)!)
request.HTTPMethod = "POST"
let params = ["name":fullName.text, "number":phoneNumber.text, "email":emailAddress.text, "timeStarted":timeStamp] as Dictionary<String, AnyObject>
request.HTTPBody = NSJSONSerialization.dataWithJSONObject(params, options: nil, error: nil)
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
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)")
let idFromServer = responseString?.valueForKeyPath("id") as String!
println(idFromServer)
var dateID = idFromServer
newUser.setValue(dateID, forKey: "dateID")

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()

HTTP response is blank

I want to send dictionary data to server but server's POST response is showing blank.
func HitApi(callback: (NSDictionary) -> Void){
let mapDict = [ "1":"First", "2":"Second"]
let json = [ "title":"ABC" , "dict": mapDict ]
let jsonData:NSData?
do {
jsonData = try NSJSONSerialization.dataWithJSONObject(json, options: .PrettyPrinted)
}catch{
jsonData = nil
}
// create post request
let url = NSURL(string: "http://myserver.com")!
let request = NSMutableURLRequest(URL: url)
request.HTTPMethod = "POST"
request.setValue("application/x-www-form-urlencoded; charset=utf-8", forHTTPHeaderField: "Content-Type")
request.setValue("application/x-www-form-urlencoded; charset=utf-8", forHTTPHeaderField: "Accept")
request.HTTPBody = jsonData
var dict = ["output":""]
let task = NSURLSession.sharedSession().dataTaskWithRequest(request){ data,response,error in
if error != nil{
dict["output"] = "An error"
callback(dict)
}
do {
let data = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.AllowFragments) as? NSDictionary
dict["output"] = NSString(data: data!, encoding: NSUTF8StringEncoding)
callback(dict)
}catch{
dict["output"] = "error"
callback(dict)
}
}
task.resume()
}
If I use this code, then everything is going fine:
func HitApi(callback: (NSDictionary) -> Void){
let dataToSend:String = "1=First&2=Second"
let jsonData:NSData?
// create post request
let url = NSURL(string: "http://myserver.com")!
let request = NSMutableURLRequest(URL: url)
request.HTTPMethod = "POST"
request.setValue("application/x-www-form-urlencoded; charset=utf-8", forHTTPHeaderField: "Content-Type")
request.setValue("application/x-www-form-urlencoded; charset=utf-8", forHTTPHeaderField: "Accept")
request.HTTPBody = dataToSend.dataUsingEncoding(NSUTF8StringEncoding)
var dict = ["output":""]
let task = NSURLSession.sharedSession().dataTaskWithRequest(request){ data,response,error in
if error != nil{
dict["output"] = "An error"
callback(dict)
}
do {
let data = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.AllowFragments) as? NSDictionary
dict["output"] = NSString(data: data!, encoding: NSUTF8StringEncoding)
callback(dict)
}catch{
dict["output"] = "error"
callback(dict)
}
}
task.resume()
}
Now server is responding fine. But if i have big nested dictionary data then this method will be fail. What is problem in my first code?

How to pass json string as parameter in swift

How to pass json as parameter string. I have tried by passing json as below but it throws error like AuthenticateUser: Invalid JSON primitive.
let jsonString = "{\"user\":\"usr\",\"password\":\"pass\"}"
var urlStr = "http://testserver/AuthenticateUser?data=\(jsonString)"
var url = NSURL(string: urlStr)
let request = NSMutableURLRequest(URL: url!)
request.URL = url
request.HTTPMethod = "POST"
request.addValue("application/xml", forHTTPHeaderField: "Content-Type")
request.addValue("application/xml", forHTTPHeaderField: "Accept")
let task = NSURLSession.sharedSession().dataTaskWithRequest(request)
{
(data, response, error) in
var error: NSError?
if data != nil {
var reply = NSString(data: data!, encoding: NSUTF8StringEncoding)
println("reply >> \(reply)")
}
}
task.resume()
Add this line after request initializtion:
request.HTTPBody = NSJSONSerialization.dataWithJSONObject(jsonString, options: nil, error: &err)
Update these lines for json format:
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
Reference:
POST with swift and API
http://jamesonquave.com/blog/making-a-post-request-in-swift/
I brought you answer up to passing json parameter as a string to URL.
var jsonString = "{\"user\":\"usr\",\"password\":\"pass\"}"
if let data = jsonString.dataUsingEncoding(NSUTF8StringEncoding)
{
var error: NSError?
var json = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.allZeros, error: &error) as? NSDictionary
if error != nil
{
println(error)
}
else
{
println(json)
}
var strUser = json?.valueForKey("user") as String
var strPassword = json?.valueForKey("password") as String
println(strUser)
println(strPassword)
var url = "http://testserver/AuthenticateUser?data="
var urlUserParameter = "user="
var urlPasswordParameter = "&password="
var appendString = "\(url)\(urlUserParameter)\(strUser)\(urlPasswordParameter)\(strPassword)"
//OR
var appendStringOne = url + urlUserParameter + strUser + urlPasswordParameter + strPassword
println(appendString)
println(appendStringOne)
}
Explanation
I converted JSON string to NSDictionary.
Then i get value using key
Finally i append all these string and now we have URL with parameters.

How to get readable JSON after NSJSONSerialization.dataWithJSONObject in Swift

I have some code similar to this (I've simplified it here):
let text = "abc" let iosVersion = UIDevice.currentDevice().systemVersion
let message = ["Text" : text, "IosVersion" : iosVersion]
if NSJSONSerialization.isValidJSONObject(message){
let url = NSURL(string: "http://localhost:3000/api/someapi")
var request = NSMutableURLRequest(URL: url!)
var data = NSJSONSerialization.dataWithJSONObject(message, options: nil, error: nil)
print(data)
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.HTTPMethod = "POST"
request.HTTPBody = data
let task = session.dataTaskWithRequest(request, completionHandler: nil)
task.resume()
}
This works fine, but I'd like to see the JSON in a readable format so that I can copy/paste it into fiddler/curl to help diagnose my API at the server end. The println(data) line above gives me hexadecimal data. Any ideas?
Create a String from Data and it's good practice to handle the error
do {
let data = try JSONSerialization.data(withJSONObject: message)
let dataString = String(data: data, encoding: .utf8)!
print(dataString)
// do other stuff on success
} catch {
print("JSON serialization failed: ", error)
}

HTTP Request with Body using PATCH in Swift

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

Resources