I'm trying to make an HTTP post request with params set in a dictionary here's my dict
let parameters = [
["name": "tag","value": "login"],
["name": "email","value": "s#s.com"],
["name": "password","value": "aaaa"]
]
but I don't to know how to access it in hers's my complete request function
func data_request(_ url:String)
{
let parameter = [
["name": "tag","value": "login"],
["name": "email","value": "s#s.com"],
["name": "password","value": "aaaa"]
]
let url:NSURL = NSURL(string: url)!
let session = URLSession.shared
let request = NSMutableURLRequest(url: url as URL)
request.httpMethod = "POST"
let paramString = parameter?
request.httpBody = paramString.data(using: String.Encoding.utf8)
let task = session.dataTask(with: request as URLRequest) {
(
data, response, error) in
guard let _:NSData = data as NSData?, let _:URLResponse = response, error == nil else {
print("error")
return
}
if let dataString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
{
print(dataString)
}
}
task.resume()
}
Need to convert dictionary to json string like below:
let jsonData = try JSONSerialization.data(withJSONObject: parameters, options: .prettyPrinted)
After that pass to the http.Body
// insert json data to the request
request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
request.HTTPBody = jsonData
let task = NSURLSession.sharedSession().dataTaskWithRequest(request){ data, response, error in
if error != nil{
print("Error -> \(error)")
return
}
do {
let result = try NSJSONSerialization.JSONObjectWithData(data!, options: []) as? [String:AnyObject]
print("Result -> \(result)")
} catch {
print("Error -> \(error)")
}
}
task.resume()
return task
} catch {
print(error)
}
You need to convert the Dictionary into Data and set it to httpBody
you could solve in this way
let paramData = try? JSONSerialization.data(withJSONObject: parameter, options: [])
request.httpBody = paramData
Related
I'm using a generic function for POST requests in my app. I have the following function:
func PostRequest<In:Codable>(object: In, endpoint: String){
do{
let url = URL(string: "http://localhost:8080/\(endpoint)/")
var request = URLRequest(url: url!)
request.httpMethod = "POST"
request.httpBody = try JSONEncoder().encode(object)
URLSession.shared.dataTask(with: request) {data, response, error in
guard let data = data, error == nil else{
print(error?.localizedDescription ?? "No Data")
return
}
let JSONResponse = try? JSONSerialization.jsonObject(with: data, options: [])
if let JSONResponse = JSONResponse as? [String: Any] {
print(JSONResponse)
}
}.resume()
}catch{
print(error)
}
}
And in this case, the object is the following struct:
struct MarkAsDelivered: Codable{
let whoCollected: String
let deliveryID: Int
}
When I print the result of JSONEncoder().encode(object) as a string, it returns the following, as would be expected:
{
"whoCollected":"TESTNAME",
"deliveryID":140
}
however, when i view this JSON object on my backend, it returns it as the following:
{
"{\"whoCollected\":\"TESTNAME\",\"deliveryID\":140}" : ""
}
From what I can tell, it is using the JSON object as a key.
Does anyone know what has caused this issue. Any assistance would be greatly appreciated.
as #burnsi mentioned in the comments to my question, I was indeed missing the content type. Specifying it fixed my issue:
func PostRequest<In:Codable>(object: In, endpoint: String){
do{
let url = URL(string: "http://localhost:8080/\(endpoint)/")
var request = URLRequest(url: url!)
request.httpMethod = "POST"
//Added content type on line below:
request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
request.httpBody = try JSONEncoder().encode(object)
URLSession.shared.dataTask(with: request) {data, response, error in
guard let data = data, error == nil else{
print(error?.localizedDescription ?? "No Data")
return
}
let JSONResponse = try? JSONSerialization.jsonObject(with: data, options: [])
if let JSONResponse = JSONResponse as? [String: Any] {
print(JSONResponse)
}
}.resume()
}catch{
print(error)
}
}
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 am trying to POST a parameter using form-data in swift.
I want to pass a mobile number with url session in form-data format. but I can't able to send data properly . please help me to pass data on form-data format in url session.
code I have Tried:
func registerService(){
print("register tapped")
let parameters: [String: Any] = [
"mobile" : mobileNumber
]
let url = URL(string: "http://54.251.198.30/api/user/login")
var req = URLRequest(url: url!)
req.httpMethod = "POST"
let boundary = "Boundary-\(UUID().uuidString)"
req.addValue("multipart/form-data : \(boundary)", forHTTPHeaderField: "Contet-Type")
req.addValue("multipart/form-data", forHTTPHeaderField: "Accept")
req.httpBody = NSKeyedArchiver.archivedData(withRootObject: parameters)
guard let httpBody = try? JSONSerialization.data(withJSONObject: parameters, options: .prettyPrinted) else {return}
req.httpBody = httpBody
let session = URLSession.shared
session.dataTask(with: req, completionHandler: {(data, response, error) in
if response != nil {
print(response)
}
if let jsonResponse = try? JSONDecoder().decode(LoginBase.self, from: data!) {
print(jsonResponse)
}else{
print("error")
}
}).resume()
}
I have added an image which parameter I want to pass. you Can see Here
thanks for your response
I have modified your function parameter as well as request-body in the correct syntax. Now you can use as follows:-
func Register(){
print("register tapped")
let parameters: [String: Any] = ["mobile" : mobileNumber] as Dictionary<String, Any>
var request = URLRequest(url: URL(string: "http://54.251.198.30/api/user/login")!)
request.httpMethod = "POST"
request.httpBody = try? JSONSerialization.data(withJSONObject: parameters, options: [])
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
let session = URLSession.shared
let task = session.dataTask(with: request, completionHandler: { data, response, error -> Void in
print(response!)
do {
let json = try JSONSerialization.jsonObject(with: data!) as! Dictionary<String, AnyObject>
print(json)
} catch {
print("error")
}
})
task.resume()
}
Hi i am new to IOS App developement.
My code is
func sendRequest<T: Decodable>(api: String, parameters: [String: String]? = nil, outputBlock: #escaping (T) -> () ) {
guard let url = URL(string: "http://xxyyzz.com/appRegister.php") else {return}
print("hitting : -", url.absoluteString)
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
let newparam = ["name": "rr", "pass": "123456", "email": "rr#rr.com", "passConfirm":"123456"]
let httpBody = try? JSONSerialization.data(withJSONObject: newparam)
request.httpBody = httpBody
if let data = request.httpBody, let str = String(data: data, encoding: String.Encoding.utf8) {
print(str)
}
URLSession.shared.dataTask(with: request as URLRequest) { (data, response, error) in
DispatchQueue.main.async {
Indicator.shared.hideProgressView()
if let err = error {
print(err.localizedDescription)
return
}
guard let data = data else {return}
do {
let obj = String(data: data, encoding: String.Encoding.utf8)
print(obj ?? "oberrrrr")
}
}
}.resume()
}
and console printed result as per code is below
hitting : - http://xxyyzz.com/appRegister.php
{"email":"rr#rr.com","passConfirm":"123456","name":"rr","pass":"123456"}
{"error":"Please enter all fields."}
url and parameters works well on postman that means their is something missing in my code.
just to answer the problem if anyone else faces this.
this code is fine but the problem was with php web-service as the backend developer was not accepting json values as parameter instead form data was need to send.
So, two types of fix can be made here
accept json at backend by adding :-
$postdata = file_get_contents("php://input");
$request = json_decode($postdata, true);
send form data instead json
func sendRequest<T: Decodable>(api: String, parameters: [String: Any]? = nil, outputBlock: #escaping (T) -> () ) {
guard let url = URL(string: api) else {return}
print("hitting : -", url.absoluteString)
var request = URLRequest(url: url)
if let parameters = parameters {
request.httpMethod = "POST"
var postArr = [String]()
for(key, value) in parameters
{
postArr.append(key + "=\(value)")
}
let postString = postArr.map { String($0) }.joined(separator: "&")
request.httpBody = postString.data(using: .utf8)
if let data = request.httpBody, let str = String(data: data, encoding: String.Encoding.utf8) {
print(str)
}
}
URLSession.shared.dataTask(with: request) { (data, response, error) in
DispatchQueue.main.async {
Indicator.shared.hideProgressView()
if let err = error {
print(err.localizedDescription)
return
}
guard let data = data else {return}
do {
let obj = try JSONDecoder().decode(T.self, from: data)
outputBlock(obj)
} catch let jsonErr {
print(jsonErr)
}
}
}.resume()
}
In the code below
let bodyData = "?sub=\(id)&name=User&email=test#test.com"
let url = NSURL(string: "https://httpbin.org/get");
let request:NSMutableURLRequest = NSMutableURLRequest(url:url as! URL)
request.httpMethod = "GET"
request.httpBody = bodyData.data(using: String.Encoding.utf8);
NSURLConnection.sendAsynchronousRequest(request as URLRequest, queue: OperationQueue.main)
{
(response, data, error) in
if let HTTPResponse = response as? HTTPURLResponse {
let statusCode = HTTPResponse.statusCode
if statusCode == 200 {
// Yes, Do something.
let json = try? JSONSerialization.jsonObject(with: data!, options: [])
if let dictionary = json as? [String: Any] {
let args = dictionary["args"]
NSLog("args:\(args)")
for (key, value) in dictionary{
NSLog("key:\(key) value:\(value)")
}
}
}
}
}
id is a string passed in to the function.
It has valid data returned, but the test site/url also returns in json format any parameters you send it. But this snippet of code seems to not be sending the query parameters defined in bodyData and I can't figure out why.
If a GET request is used the parameters are appended to the URL and an explicit URLRequest is not needed at all.
This code is native Swift 3 and uses contemporary API:
let id = 12
let bodyData = "?sub=\(id)&name=User&email=test#test.com"
let url = URL(string: "https://httpbin.org/get" + bodyData)!
URLSession.shared.dataTask(with: url) { (data, response, error) in
if error != nil {
print(error!)
return
}
do {
if let json = try JSONSerialization.jsonObject(with: data!, options: []) as? [String:Any],
let args = json["args"] as? [String:Any] {
print("args:\(args)")
for (key, value) in args{
print("key:\(key) value:\(value)")
}
}
} catch {
print(error)
}
}.resume()