Swift: How to add Dictionary format in forHTTPHeaderField in GET request - swift

In GET request, I am trying to add header.
request.setValue(value: String?, forHTTPHeaderField: "SessionInfo")
But, SessionInfo value is in [String : Any]
Attempt 1:
func SO_Function() {
let service_url = WebService.sharedManager().serviceURL
let getMenuURL = service_url + "/MyPage/FileDownload.ashx"
var convertedString = ""
do {
let data1 = try JSONSerialization.data(withJSONObject: WebService.sharedManager().mobInfoDict, options: [])
convertedString = String(data: data1, encoding: .utf8)!
print("\n\nconvertedJSONtoData ", convertedString)
} catch {
print("\n\nCAtcLL___Err ",error.localizedDescription)
}
let url = NSURL(string: getMenuURL)
let request = NSMutableURLRequest(url: url! as URL)
//Below line, If I can able to add [String:Any] then I will get
proper Image as output.
request.setValue(convertedString, forHTTPHeaderField: "SessionInfo")
request.setValue("67a2a6fb1d13450a", forHTTPHeaderField: "Flowid")
request.setValue("d29566ac42de4e99", forHTTPHeaderField: "Fileid")
request.setValue("LMS_LEAVEREQUEST", forHTTPHeaderField: "Form")
request.httpMethod = "GET"
let session = URLSession.shared
let mData = session.dataTask(with: request as URLRequest) { (data, response, error) -> Void in
if let res = response as? HTTPURLResponse {
DispatchQueue.main.async {
let img = UIImage(data: data!)
self.attachmentImgVw.image = img
}
}else{
print("\n\nError: \(String(describing: error))")
}
}
mData.resume()
}
Output
The data couldn’t be read because it isn’t in the correct format.
Error ScreenShot 1:
Postman Screenshot
In postman, I am giving SessionInfo value as in Dictionary format. Working fine.
How to solve this issue?

Related

How to use json response as parameter in another api post call?

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

URL Session Post with form-data parameter in iOS Swift

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

urlrequest not sending post request

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

Swift 3 How To Send A Multipart Post Request With Vapor

I'm using vapor to host images for my app.I have the following code to recieve the image and print it.
drop.post("saveArt") { request in
if let contentType = request.headers["Content-Type"], contentType.contains("image/png"), let bytes = request.body.bytes {
let image = NSImage(data: Data(bytes))
print(image)
return JSON(["Testawesome":"awesome123"])
}
return JSON(["test":"123"])
}
How can I send a multipart request using just swift?.Here is the current post request code i'm using.
let tiffData = imagetosend?.tiffRepresentation
let imageRep = NSBitmapImageRep(data: tiffData!)
let image_data = imageRep?.representation(using: .JPEG, properties: [:])
print("Hi")
let url = NSURL(string: "http://localhost:8080/getArt")
let request = NSMutableURLRequest(url: url! as URL)
request.httpMethod = "POST"
//define the multipart request type
request.setValue("multipart/form-data", forHTTPHeaderField: "Content-Type")
let body = NSMutableData()
let mimetype = "image/png"
//define the data post parameter
body.append("Content-Type: \(mimetype)\r\n\r\n".data(using: String.Encoding.utf8)!)
body.append(image_data!)
body.append("\r\n".data(using: String.Encoding.utf8)!)
request.httpBody = body as Data
let session = URLSession.shared
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?.localizedDescription)
return
}
let dataString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
print(dataString)
}
task.resume()
I solved it using this alamofire method.
Alamofire.request("YOUR URL", method: .post, parameters: parm, encoding: JSONEncoding.default).responseJSON(completionHandler: { json in
// If you want to return json.
print(json)
})

How can i convert String to Dictionary to access nested array and dictionary, i want to access stateId and stateName to add in to my table

i
func callAddWithPOST(Name mname:String, PhoneNo mphone:String, Email memail:String, Comment mcomments:String){
let login = ["countryId":"1"]
print("Your Result is : = \(login)")
let url = NSURL(string: "http://photokeeper.mgtcloud.co.uk/commonwebservice.asmx/getStateList")!
let session = NSURLSession.sharedSession()
let request = NSMutableURLRequest(URL: url)
do {
let auth = try NSJSONSerialization.dataWithJSONObject(login, options: .PrettyPrinted)
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.HTTPMethod = "POST"
request.HTTPBody = auth
let task = session.dataTaskWithRequest(request, completionHandler: { (data, response, error) -> Void in
let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding)
let result = self.convertStringToDictionary(responseString!)
let keys = Array(result!.values)
print(keys[0])
print("Done.")
})
task.resume()
} catch {
print("Error")
}
}
output
{"result":[{"stateId":3871,"stateName":"Aberdeenshire"},{"stateId":3872,"stateName":"Anglesey/Sir Fon"},{"stateId":3873,"stateName":"Angus"},{"stateId":3874,"stateName":"Antrim"},{"stateId":3875,"stateName":"Argyll And Bute"},{"stateId":3876,"stateName":"Armagh"},{"stateId":3877,"stateName":"Ayrshire"},{"stateId":3878,"stateName":"Bedfordshire"},{"stateId":3879,"stateName":"Berkshire"},{"stateId":3880,"stateName":"Blaenau Gwent/Blaenau Gwent"},{"stateId":3881,"stateName":"Bristol"},{"stateId":3882,"stateName":"Buckinghamshire"},{"stateId":3883,"stateName":"Caerphilly/Caerffili"},{"stateId":3884,"stateName":"Cambridgeshire"},{"stateId":3885,"stateName":"Cardiff/Caerdydd"},{"stateId":3886,"stateName":"Cardiganshire/Ceredigion"},{"stateId":3888,"stateName":"Carmarthenshire/Sir Gaerfyrddin"},{"stateId":3890,"stateName":"Cheshire"},{"stateId":3891,"stateName":"Clackmannanshire"},{"stateId":3893,"stateName":"Conwy/Conwy"},{"stateId":3895,"stateName":"County Durham"},{"stateId":3896,"stateName":"Cumbria"},{"stateId":3897,"stateName":"Denbighshire/Sir Ddinbych"},{"stateId":3898,"stateName":"Derbyshire"},{"stateId":3899,"stateName":"Devon"},{"stateId":3901,"stateName":"Dorset"},{"stateId":3902,"stateName":"Down"},{"stateId":3904,"stateName":"Dumfries And Galloway"},{"stateId":3905,"stateName":"Dunbartonshire"},{"stateId":3906,"stateName":"Dundee"},{"stateId":3907,"stateName":"Durham/North Yorkshire"},{"stateId":3908,"stateName":"East Lothian"},{"stateId":3909,"stateName":"East Sussex"},{"stateId":3910,"stateName":"East Yorkshire"},{"stateId":3911,"stateName":"Edinburgh"},{"stateId":3912,"stateName":"Essex"},{"stateId":3913,"stateName":"Fermanagh"},{"stateId":3914,"stateName":"Fife"},{"stateId":3915,"stateName":"Flintshire/Sir Fflint"},{"stateId":3917,"stateName":"Glamorgan/Morgannwg"},{"stateId":3918,"stateName":"Glasgow"},{"stateId":3919,"stateName":"Gloucestershire"},{"stateId":3920,"stateName":"Gwynedd/Gwynedd"},{"stateId":3921,"stateName":"Hampshire"},{"stateId":3922,"stateName":"Herefordshire"},{"stateId":3923,"stateName":"Hertfordshire"},{"stateId":3924,"stateName":"Highland"},{"stateId":3925,"stateName":"Kent"},{"stateId":3929,"stateName":"Lanarkshire"},{"stateId":3930,"stateName":"Lancashire"},{"stateId":3932,"stateName":"Leicestershire"},{"stateId":3935,"stateName":"Lincolnshire"},{"stateId":3936,"stateName":"London"},{"stateId":3937,"stateName":"Londonderry"},{"stateId":3940,"stateName":"Manchester"},{"stateId":3943,"stateName":"Merthyr Tydfil/Merthyr Tydfil"},{"stateId":3944,"stateName":"Midlothian"},{"stateId":3946,"stateName":"Monmouthshire/Sir Fynwy"},{"stateId":3947,"stateName":"Moray"},{"stateId":3948,"stateName":"Neath Port Talbot"},{"stateId":3949,"stateName":"Newport"},{"stateId":3950,"stateName":"Norfolk"},{"stateId":3951,"stateName":"Northamptonshire"},{"stateId":3952,"stateName":"Northumberland"},{"stateId":3953,"stateName":"Nottinghamshire"},{"stateId":3955,"stateName":"Orkney"},{"stateId":3956,"stateName":"Oxfordshire"},{"stateId":3957,"stateName":"Pembrokeshire/Sir Benfro"},{"stateId":3958,"stateName":"Perth And Kinross"},{"stateId":3959,"stateName":"Powys/Powys"},{"stateId":3960,"stateName":"Renfrewshire"},{"stateId":3962,"stateName":"Rutland"},{"stateId":3963,"stateName":"Scottish Borders"},{"stateId":3964,"stateName":"Shetland Isles"},{"stateId":3965,"stateName":"Shropshire"},{"stateId":3967,"stateName":"Somerset"},{"stateId":3968,"stateName":"South Yorkshire"},{"stateId":3969,"stateName":"Staffordshire"},{"stateId":3970,"stateName":"Stirling"},{"stateId":3971,"stateName":"Suffolk"},{"stateId":3972,"stateName":"Surrey"},{"stateId":3973,"stateName":"Swansea"},{"stateId":3975,"stateName":"Torfaen"},{"stateId":3976,"stateName":"Tyrone"},{"stateId":3977,"stateName":"Warwickshire"},{"stateId":3979,"stateName":"West Lothian"},{"stateId":3980,"stateName":"West Midlands"},{"stateId":3981,"stateName":"West Sussex"},{"stateId":3982,"stateName":"West Yorkshire"},{"stateId":3983,"stateName":"Western Isles"},{"stateId":3987,"stateName":"Wiltshire"},{"stateId":3988,"stateName":"Worcestershire"},{"stateId":3989,"stateName":"Wrexham"}],"status":"success"}
Done.
Instead of converting data to String try to convert it Dictionary direct
let task = session.dataTaskWithRequest(request, completionHandler: { (data, response, error) -> Void in
let response = try NSJSONSerialization.JSONObjectWithData(data!, options:.MutableContainers) as! [String: AnyObject]
let status = response["status"] as! String
if status == "success" {
let array = response["result"] as! [[String: AnyObject]]
print(array)
}
})
Note: You have already written your code inside do block thats why i have not declare that block for try, you just need to replace your task block with my one.
Edit:
func callAddWithPOST(Name mname:String, PhoneNo mphone:String, Email memail:String, Comment mcomments:String){
let login = ["countryId":"1"]
print("Your Result is : = \(login)")
let url = NSURL(string: "http://photokeeper.mgtcloud.co.uk/commonwebservice.asmx/getStateList")!
let session = NSURLSession.sharedSession()
let request = NSMutableURLRequest(URL: url)
do {
let auth = try NSJSONSerialization.dataWithJSONObject(login, options: .PrettyPrinted)
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.HTTPMethod = "POST"
request.HTTPBody = auth
let task = session.dataTaskWithRequest(request, completionHandler: { (data, response, error) -> Void in
let response = try NSJSONSerialization.JSONObjectWithData(data!, options:.MutableContainers) as! [String: AnyObject]
let status = response["status"] as! String
if status == "success" {
let array = response["result"] as! [[String: AnyObject]]
print(array)
}
})
task.resume()
} catch let error as NSError {
print(error.localizedDescription)
}
}