I have the parameters which has to be saved to database using post method api.
The property_image_url is ["https://res.cloudinary.com/dtwvevtm7/image/upload/v1617203478/j8mqat97ssrctsnzpjlc.jpg","https://res.cloudinary.com/dtwvevtm7/image/upload/v1617203479/j1rhedrsnrud7fkva1bl.jpg"]
The parameters are as follows:
["price": "dry", "listing_description": "Dghb", "listing_type": "Residential", "property_image_url": "[\"https://res.cloudinary.com/dtwvevtm7/image/upload/v1617203478/j8mqat97ssrctsnzpjlc.jpg\",\"https://res.cloudinary.com/dtwvevtm7/image/upload/v1617203479/j1rhedrsnrud7fkva1bl.jpg\"]", "address": "chennai ", "listing_use": "SubLease", "property_video_url": "", "title": "huffy"]
Here when the value is property_image_url,it is showing unnescessary white space and escape character.
The code used to post the data via API is given below:
let url = URL(string: url)! //change the url
//create the session object
let session = URLSession.shared
//now create the URLRequest object using the url object
var request = URLRequest(url: url)
request.httpMethod = "POST" //set http method as POST
do {
request.httpBody = try JSONSerialization.data(withJSONObject: parameter, options: .fragmentsAllowed) // pass dictionary to nsdata object and set it as request body
} catch let error {
print(error.localizedDescription)
}
request.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.addValue(self.usertoken, forHTTPHeaderField: "x-token")
//create dataTask using the session object to send data to the server
let task = session.dataTask(with: request as URLRequest, completionHandler: { data, response, error in
print("data is",data)
guard error == nil else {
return
}
guard let data = data else {
return
}
do {
//create json object from data
if let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String: Any] {
print("new listing json is",json)
DispatchQueue.main.async {
self.navigationController?.view.makeToast("Listing Updated successfully", duration: 3.0, position: .bottom)
let vc = self.storyboard?.instantiateViewController(withIdentifier: "Home") as! Home
self.navigationController?.pushViewController(vc, animated: true)
}
}
} catch let error {
print(error.localizedDescription)
}
})
task.resume()
}
This post method is throwing error saying
["errors": <__NSArrayM 0x283120810>(
Title Required,
Listing Type Required,
Listing Use Required
)
]
Here,in the parameter all these values are filled but still it is showing like that these values are empty.
Let me know what is the issue in passing the parameter and calling the API.
Related
I make a GET call and receive a json response. I need to use that json response as one parameter for a subsequent POST call.
I’ve tried to:
-parse the data into an object and pass the [object] as parameter
-parse the data into a string and pass the string as parameter
-parse the data as dict and pass the dict as parameter
but it’s not working, I believe it’s a data thing or a secret I’m missing
How do you use a json response as parameter for a subsequent api call?
//MARK: - PIXLAB facedetect
func facedetectGET(uploadedUrl: String) {
var urlComponents = URLComponents(string: "https://api.pixlab.io/facedetect")
urlComponents?.queryItems = [
URLQueryItem(name: "img", value: uploadedUrl),
URLQueryItem(name: "key", value: Constants.pixlabAPIkey),
]
let url = urlComponents?.url
if let url = url {
// Create URL Request
var request = URLRequest(url: url, cachePolicy: .reloadIgnoringLocalCacheData, timeoutInterval: 10.0)
request.httpMethod = "GET"
request.addValue("Bearer \(Constants.pixlabAPIkey)", forHTTPHeaderField: "Authorization")
// Get URLSession
let session = URLSession.shared
// Create Data Task
let dataTask = session.dataTask(with: request) { (data, response, error) in
// Check that there isn't an error
if error == nil {
do {
let json = try JSONSerialization.jsonObject(with: data!, options: [])
//make a dict
//let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? [String: Any]
print("SUCCESS: image detected")
print(json)
//make json a string utf8 so it can be used as parameter in next call
//let jsonString = String(data: json as! Data, encoding: .utf8)
//let jsonData = json.data(using: .utf8)!
//parse json
//decode the json to an array of faces
let faces: [Face] = try! JSONDecoder().decode([Face].self, from: data!)
let facesString = String(faces)
//use dispatch main sync queue??"bottom": Int,
//mogrify call
mogrify(uploadedUrl: uploadedUrl, cord: faces)
}
catch {
print(error)
}
}
}
// Start the Data Task
dataTask.resume()
}
}
//MOGRIFY CALL
func mogrify(uploadedUrl: String, cord: Any) {
let mogrifyurl = URL(string: "https://api.pixlab.io/mogrify")!
//let param: [Face] = result.faces
let param: [String: Any] = ["img": uploadedUrl, "cord": cord]
var request = URLRequest(url: mogrifyurl)
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("Bearer \(Constants.pixlabAPIkey)", forHTTPHeaderField: "Authorization")
request.httpMethod = "POST"
request.httpBody = try! JSONSerialization.data(withJSONObject: param, options: [])
URLSession.shared.dataTask(with: request) { (data, response, error) in
if error != nil {
print(error!)
return
}
do {
let json = try JSONSerialization.jsonObject(with: data!)
print(json)
} catch {
print("error")
}
}.resume()
}
this is how pretty the response looks
enter image description here
and this is how it looks when I pass it as parameter
enter image description here
A POST needs the body as Data. If you're just forwarding the body of the GET to the body of the POST, it would be easiest to leave it as Data.
You could also deserialize the response into an object in your get, and then re-serialize it back into Data in the POST code, but why?
I did lots of white magic, voodoo and lots of praying (aka try and error) and I made it work…
basically decoded the json data, then got an array subdata and encode it back into a data variable as input for the post call
maybe there is an easier and more elegant way but this works....
do {
//decode the json to an array of faces
let cord = try! JSONDecoder().decode(Cord.self, from: data!)
print(cord.faces)
let cordData = try! JSONEncoder().encode(cord.faces)
let coordinates = try JSONSerialization.jsonObject(with: cordData, options: [])
print(coordinates)
//mogrify call
mogrify(uploadedUrl: uploadedUrl, cord: coordinates)
} catch {
print(error)
}
post call
//MOGRIFY CALL
func mogrify(uploadedUrl: String, cord: Any) {
let mogrifyurl = URL(string: "https://api.pixlab.io/mogrify")!
// let param: [Face] = result.faces
let param: [String: Any] = ["img": uploadedUrl, "key": Constants.pixlabAPIkey, "cord": cord]
var request = URLRequest(url: mogrifyurl)
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("Bearer \(Constants.pixlabAPIkey)", forHTTPHeaderField: "Authorization")
request.httpMethod = "POST"
request.httpBody = try! JSONSerialization.data(withJSONObject: param, options: [])
URLSession.shared.dataTask(with: request) { (data, response, error) in
if error != nil {
print(error!)
return
}
do {
let json = try JSONSerialization.jsonObject(with: data!)
print("MOGRIFY response")
print(json)
} catch {
print("error")
}
}.resume()
}
I have tried to research this issue and am unable to find a suitable fix. I attached an image of the code. I am trying to return the subscriptions array which is declared before the URLSession, and data is appended during the URLSession. However, it returns the originally declared, empty array. I added print statements so you can understand what I am talking about. It prints 2 before 1.
let request = NSMutableURLRequest(url: NSURL(string: "https://utelly-tv-shows-and-movies-availability-v1.p.rapidapi.com/lookup?term=\(searchShow)&country=us")! as URL, cachePolicy: .useProtocolCachePolicy,timeoutInterval: 10.0)
request.httpMethod = "GET"
request.allHTTPHeaderFields = headers
let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
if (error != nil) {
//let json = try? JSONSerialization.jsonObject(with: data!, options: [])
//print(json)
} else {
//let httpResponse = response as? HTTPURLResponse
let decoder = JSONDecoder()
let json = try! decoder.decode(results.self, from: data!)
//print(json) (for debugging use only)
//print(httpResponse)
for item in json.results{
for each in item.locations{
subscriptions.append(each.display_name)
}
}
//Remove duplicates from array
let uniqueUnordered = Array(Set(subscriptions))
let uniqueOrdered = Array(NSOrderedSet(array: uniqueUnordered))
subscriptions = uniqueOrdered as! [String]
//Print subscriptions array
print("1: \(subscriptions)")
}
})
dataTask.resume()
print("2: \(subscriptions)")
return subscriptions
I'm modifying code from 'Hacking with swift' Project 7 to take a JSON file using an API and placing it in a table view
I'm at a bit of loss of what to do next, tried moving around the call to the parse function and using the commented out code
override func viewDidLoad() {
super.viewDidLoad()
let username = "UserName"
let password = "Password"
let loginData = String(format: "%#:%#", username,
password).data(using: String.Encoding.utf8)!
let base64LoginData = loginData.base64EncodedString()
let url = URL(string: "......")!
var request = URLRequest(url: url)
request.httpMethod = "GET"
request.setValue("Basic \(base64LoginData)", forHTTPHeaderField:
"Authorization")
let task = URLSession.shared.dataTask(with: request) { data,
response,
error in
guard let data = data, error == nil else {
print("error")
return
}
if let httpStatus = response as? HTTPURLResponse {
parse(json: data)
print("status code = \(httpStatus.statusCode)")
}
}
task.resume()
}
// if let url = URL(string: urlstring){
// if let data = try? Data(contentsOf: url){
// parse(json: data)
// return
// }
// }
// showError()
//}
func parse(json: Data) {
let decoder = JSONDecoder()
if let jsonPetitions = try? decoder.decode(Petitions.self, from:
json) {
petitions = jsonPetitions.results
tableView.reloadData()
}
}
I receive a status code of '200' so I know the API call works fine.
The issue seems to be with calling the parse function I get the
following error "Call to method 'parse' in closure requires explicit
'self.' to make capture semantics explicit"
1- The error means to add self here
self.parse(json: data)
2- You should reload the table in main thread as callback of URLSession.shared.dataTask runs in a background thread to avoid un-expected results/crashes
DispatchQueue.main.async {
self.tableView.reloadData()
}
I've wrote a function for GET request from rest and it says that i have method not allowed - code 405 which is werid and i can not find solution for that.
I am doing GET via current token which was assigned to the user after logged in.
Could someone have a look on the code and tell me what might be wrong ?
func getRequest() -> Void {
let json: [String: Any] = ["token": SessionMenager.Instance.token]
let jsonData = try? JSONSerialization.data(withJSONObject: json)
// create post request
let url = URL(string: MY_URL)!
var request = URLRequest(url: url)
request.httpMethod = "GET"
// insert json data to the request
request.httpBody = jsonData
request.setValue("application/json;charest=utf-8", forHTTPHeaderField: "Content-Type")
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data, error == nil else {
print(error?.localizedDescription ?? "No data")
return
}
if let httpResponse = response as? HTTPURLResponse {
print("GET : code - \(httpResponse.statusCode)")
}
let responseJSON = try? JSONSerialization.jsonObject(with: data, options: [])
if let responseJSON = responseJSON as? [String: Any] {
print(responseJSON)
} else{
print(error.debugDescription)
}
}
task.resume()
}
Thanks in advance!!
I am building an app using Swift 3.0 for study purpose.
One of the functions is to fetch and save data from(to) SQL Server database tables. One of the columns is to store IMAGE(photo) in table: data type in table is Image (system.Byte[]) in SQL Server.
I can get the photo column through web api and show it in Image component like this:
let encodedImageData = My web api url
let imageData = NSData(base64EncodedString: encodedImageData options: .allZeros)
let image = UIImage(data: imageData)
let imageView.image = image
I had problem to save the Image to the database through web api (can save other columns, but had problem with Image column).
I tried this:
let data = UIImagePNGRepresentation(image) as NSData?
but failed.
my web api and invoke as below:
func post(parameters : Dictionary<String, String>, urlString : String) {
var request = URLRequest(url: URL(string: urlString)!)
let session = URLSession.shared
request.httpMethod = "POST"
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
request.httpBody = try! JSONSerialization.data(withJSONObject: parameters)
let task = session.dataTask(with: request) { data, response, error in
guard let data = data, error == nil else {
print("error: \(error)")
return
}
do {
if let json = try JSONSerialization.jsonObject(with: data) as? [String: Any] {
let success = json["success"] as? Int // Okay, the `json` is here, let's get the value for 'success' out of it
print("Success: \(success)")
} else {
let jsonStr = String(data: data, encoding: .utf8) // No error thrown, but not dictionary
print("Error could not parse JSON: \(jsonStr)")
}
} catch let parseError {
print(parseError) // Log the error thrown by `JSONObjectWithData`
let jsonStr = String(data: data, encoding: .utf8)
print("Error could not parse JSON: '\(jsonStr)'")
}
}
task.resume()
}
#IBAction func insert(){
let imageData = UIImagePNGRepresentation(myimageview.image!) as NSData?
post(parameters: ["Name": nametxt.text!,"Address": addresstxt.text!,"photoname": photonametxt.text!,"photo": String(describing: imageData),"url": urltxt.text! ], urlString: "http://XXXXXXX/api/myfavorites")
}
Can someone help me have a look at image save method to database table in Swift?
I think you are using the wrong data structure for your image. Instead of using NSData and String(describing:) (which definitely does not do what you want), you should directly use a base64 encoded string, like the following code:
#IBAction func insert(){
let imageBase64String = UIImagePNGRepresentation(myimageview.image!)?.base64EncodedString()
post(parameters: ["Name": nametxt.text!,"Address": addresstxt.text!,"photoname": photonametxt.text!,"photo": imageBase64String,"url": urltxt.text! ], urlString: "http://XXXXXXX/api/myfavorites")
}