How to add request.httpBody = getPostData(params: ["contactsList": ["1212121212, "5555555544"]]) in place of
let parameters = getPostString(params: ["contactsList":[phNumArray]])
below is working code but how to add phNumArray in palce of individual of individual numberes to contactsList
Postman output for API:
working code: anyone can copy paste to see output
import UIKit
class TestViewController: UIViewController {
var phNumArray = ["1111111111", "5555555544"]
override func viewDidLoad() {
super.viewDidLoad()
callPostApi()
}
func getPostString(params: [String: Any]) -> String {
var data = [String]()
for (key, value) in params {
data.append(key + "=\(value)")
}
print(data.map { String($0) }.joined(separator: "&"))
return data.map { String($0) }.joined(separator: "&")
}
func callPostApi() {
let url = URL(string: "http://itaag-env-1.ap-south-1.elasticbeanstalk.com/filter/taggedusers/")
guard let requestUrl = url else { fatalError() }
var request = URLRequest(url: requestUrl)
request.httpMethod = "POST"
request.setValue("EC3746E9-4DB4-42C7-9D8C-1542B18C2AC", forHTTPHeaderField: "deviceid")
request.setValue("5fe42fb3b54543a0bab5667cf96526f8", forHTTPHeaderField: "key")
request.setValue("personal", forHTTPHeaderField: "userType")
let parameters = getPostString(params: ["contactsList": ["5555555544", "11111111111"]])
print("json parameter phone numbers \(parameters)")
request.httpBody = parameters.data(using: .utf8)
let task = URLSession.shared.dataTask(with: request) { data, response, error in
let httpResponse = response as? HTTPURLResponse
// Check for Error
if let error = error {
print("Error took place \(error)")
return
}
if let data = data, let dataString = String(data: data, encoding: .utf8) {
print("Response data string:\n \(dataString)")
do {
let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as! [String: Any]
print("fetching json \(json)")
let fetchStatus = json["userName"] as? String
print("fetching json userName \(String(describing: fetchStatus))")
let user = json["5555555544"] as? [String: Any]
let name = user?["userName"] as? String
print("first username \(name)")
} catch {}
}
}
task.resume()
}
}
please help me to solve the issue with contactsList value.
Update: All this time you were sending the request as JSON encoded instead of as form-data. I'm adding the code for that below, try it out:
class ViewController: UIViewController {
var phNumArray = ["1111111111", "5555555544"]
override func viewDidLoad() {
super.viewDidLoad()
callPostApi()
}
func getPostData(params: [String:Any]) -> Data? {
return try? JSONSerialization.data(withJSONObject: params, options: .prettyPrinted)
}
func callPostApi() {
let url = URL(string: "http://itaag-env-1.ap-south-1.elasticbeanstalk.com/filter/taggedusers/")!
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("EC3746E9-4DB4-42C7-9D8C-1542B18C2AC", forHTTPHeaderField: "deviceid")
request.setValue("5fe42fb3b54543a0bab5667cf96526f8", forHTTPHeaderField: "key")
request.setValue("personal", forHTTPHeaderField: "userType")
try? request.setMultipartFormData(["contactsList": "\(phNumArray)"], encoding: .utf8)
URLSession.shared.dataTask(with: request) { data, _, _ in
if let data = data, let json = try? JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String: Any] {
let user = json["5555555544"] as? [String: Any]
let name = user?["userName"] as? String
print("first username \(name)")
}
}.resume()
}
}
extension URLRequest {
public mutating func setMultipartFormData(_ parameters: [String: String], encoding: String.Encoding) throws {
let makeRandom = { UInt32.random(in: (.min)...(.max)) }
let boundary = String(format: "------------------------%08X%08X", makeRandom(), makeRandom())
let contentType: String = try {
guard let charset = CFStringConvertEncodingToIANACharSetName(CFStringConvertNSStringEncodingToEncoding(encoding.rawValue)) else {
throw MultipartFormDataEncodingError.characterSetName
}
return "multipart/form-data; charset=\(charset); boundary=\(boundary)"
}()
addValue(contentType, forHTTPHeaderField: "Content-Type")
httpBody = try {
var body = Data()
for (rawName, rawValue) in parameters {
if !body.isEmpty {
body.append("\r\n".data(using: .utf8)!)
}
body.append("--\(boundary)\r\n".data(using: .utf8)!)
guard
rawName.canBeConverted(to: encoding),
let disposition = "Content-Disposition: form-data; name=\"\(rawName)\"\r\n".data(using: encoding) else {
throw MultipartFormDataEncodingError.name(rawName)
}
body.append(disposition)
body.append("\r\n".data(using: .utf8)!)
guard let value = rawValue.data(using: encoding) else {
throw MultipartFormDataEncodingError.value(rawValue, name: rawName)
}
body.append(value)
}
body.append("\r\n--\(boundary)--\r\n".data(using: .utf8)!)
return body
}()
}
}
public enum MultipartFormDataEncodingError: Error {
case characterSetName
case name(String)
case value(String, name: String)
}
Instead of converting to JSON String and then converting it to Data, use JSONSerialization, here's an example:
func getPostData(params:[String:Any]) -> Data? {
return try? JSONSerialization.data(withJSONObject: params, options: .prettyPrinted)
}
And then assign it directly to URLRequest's httpBody, like this:
let arrayOfNumbers = [String]()
arrayOfNumbers.append("5555555544")
arrayOfNumbers.append("11111111111")
request.httpBody = getPostData(params: ["contactsList": arrayOfNumbers])
Also, go through the Apple Documentation, you'll find valuable information there. If don't understand concepts there google more about JSONSerializing and POST request httpBody.
How to pass the JSON data from HTTP request to another view controller in swift 3? This function is when selected a cell, It will get the JSON data from server then I have to pass the JSON data to another view controller.
func retrieveTime(jobDateValue: String) -> Void {
if let crew = user!["crew"] as? [String:Any], let crewID = crew["crew_id"] as? String{
let param = ["action": "retrieve time", "job": ["crew_id": crewID, "jobDate": jobDateValue]] as [String : Any]
let headers = [
"content-type": "application/json",
"cache-control": "no-cache"
]
if let postData = (try? JSONSerialization.data(withJSONObject: param, options: [])) {
let request = NSMutableURLRequest(url: URL(string: "http://52.221.231.3/gv/app_api.php")!,
cachePolicy: .useProtocolCachePolicy,
timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData
_ = URLSession.shared
let task = URLSession.shared.dataTask(with: request as URLRequest) {
(data, response, error) -> Void in
DispatchQueue.main.async(execute: {
if let json = (try? JSONSerialization.jsonObject(with: data!, options: [.mutableContainers])) as? NSDictionary
{
let result = json["result"] as? String
if (result == "success") {
let passValue = json
}else{
}
}
})
}
task.resume()
}
}
}
passing json data to second view controller
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "SecondVCSegue"{
if let destination = segue.destination as? SecondVC {
destination.passedData = json
}
}
}
JSON Output:
{
jobs = (
{
jobDate = "2017-09-01";
jobEndTime = 1504231200;
jobID = 88;
jobTime = 1504224000;
}
);
message = "Retrieve Sucessfully";
result = success;
}
You should set up a manual segue in Storyboard, that you only call inside the completion handler of your network request. If the segue is connected to a single tableview cell, it will be called by the system before your async function would finish execution. Once you changed your segue to be manual and not connected to a static table view cell, you can call it using the function performSegue.
func retrieveTime(jobDateValue: String) -> Void {
if let crew = user!["crew"] as? [String:Any], let crewID = crew["crew_id"] as? String{
let param = ["action": "retrieve time", "job": ["crew_id": crewID, "jobDate": jobDateValue]] as [String : Any]
let headers = [ "content-type": "application/json", "cache-control": "no-cache" ]
if let postData = (try? JSONSerialization.data(withJSONObject: param, options: [])) {
var request = URLRequest(url: URL(string: "http://52.221.231.3/gv/app_api.php")!, cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData
let task = URLSession.shared.dataTask(with: request) { (data, response, error) -> Void in
guard error == nil, let data = data else {return}
DispatchQueue.main.async{
if let json = (try? JSONSerialization.jsonObject(with: data)) as? [String:Any]{
let result = json["result"] as? String
if (result == "success") {
let passValue = json
self.performSegue(withIdentifier: "YourSegue", sender: json)
} else{
}
}
}
}
task.resume()
}
}
}
Also use native Swift objects when available instead of their Foundation counterparts (such as NSDictionary, NSMutableURLRequest).
You should also use the sender option of performSegue to send the json data to your other view controller instead of storing it in another variable unless you use the json object in your first view controller as well.
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "SecondVCSegue"{
if let destination = segue.destination as? SecondVC, let json = sender as? [String:Any] {
destination.passedData = json
}
}
}
I'm trying to make an HTTP post request with a JSON body :
How to be able to add an NSdictionnary to the HTTP request body.
Here is my code, it doesn't seem to work properly.
var entry1 = Response(IdQuestion: 6510,IdProposition: 10,Time: 30)
var entry2 = Response(IdQuestion: 8284,IdProposition: 10,Time: 30)
Responses.append(entry1)
Responses.append(entry2)
let list = Responses.map { $0.asDictionary }
let json = ["List":list,"IdSurvey":"102","IdUser":"iOSclient","UserInformation":"iOSClient"]
let data: NSData = NSKeyedArchiver.archivedDataWithRootObject(json)
NSJSONSerialization.isValidJSONObject(json)
let myURL = NSURL(string: "http://www.myserver.com")!
let request = NSMutableURLRequest(URL: myURL)
request.HTTPMethod = "POST"
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.setValue("application/json", forHTTPHeaderField: "Accept")
request.HTTPBody = data
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
data, response, error in
println(response)
// Your completion handler code here
}
task.resume()
Try this,
// prepare json data
let json: [String: Any] = ["title": "ABC",
"dict": ["1":"First", "2":"Second"]]
let jsonData = try? JSONSerialization.data(withJSONObject: json)
// create post request
let url = URL(string: "http://httpbin.org/post")!
var request = URLRequest(url: url)
request.httpMethod = "POST"
// insert json data to the request
request.httpBody = jsonData
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data, error == nil else {
print(error?.localizedDescription ?? "No data")
return
}
let responseJSON = try? JSONSerialization.jsonObject(with: data, options: [])
if let responseJSON = responseJSON as? [String: Any] {
print(responseJSON)
}
}
task.resume()
or try a convenient way Alamofire
Swift 4 and 5
HTTP POST request using URLSession API in Swift 4
func postRequest(username: String, password: String, completion: #escaping ([String: Any]?, Error?) -> Void) {
//declare parameter as a dictionary which contains string as key and value combination.
let parameters = ["name": username, "password": password]
//create the url with NSURL
let url = URL(string: "https://www.myserver.com/api/login")!
//create the session object
let session = URLSession.shared
//now create the Request 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: parameters, options: .prettyPrinted) // pass dictionary to data object and set it as request body
} catch let error {
print(error.localizedDescription)
completion(nil, error)
}
//HTTP Headers
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
//create dataTask using the session object to send data to the server
let task = session.dataTask(with: request, completionHandler: { data, response, error in
guard error == nil else {
completion(nil, error)
return
}
guard let data = data else {
completion(nil, NSError(domain: "dataNilError", code: -100001, userInfo: nil))
return
}
do {
//create json object from data
guard let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String: Any] else {
completion(nil, NSError(domain: "invalidJSONTypeError", code: -100009, userInfo: nil))
return
}
print(json)
completion(json, nil)
} catch let error {
print(error.localizedDescription)
completion(nil, error)
}
})
task.resume()
}
#objc func submitAction(_ sender: UIButton) {
//call postRequest with username and password parameters
postRequest(username: "username", password: "password") { (result, error) in
if let result = result {
print("success: \(result)")
} else if let error = error {
print("error: \(error.localizedDescription)")
}
}
Using Alamofire:
let parameters = ["name": "username", "password": "password123"]
Alamofire.request("https://www.myserver.com/api/login", method: .post, parameters: parameters, encoding: URLEncoding.httpBody)
HTTP Post in Swift capturing the errors
let json = [ Activity.KEY_IDSUBJECT : activity.idSubject, Activity.KEY_RECORDMODE : "3", Activity.KEY_LOCATION_LONGITUDE : "0",Activity.KEY_LOCATION_LATITUDE : "0", Activity.KEY_CHECKIN : String(activity.dateCheckIn), Activity.KEY_CHECKOUT : String(activity.dateCheckOut) ]
do {
let jsonData = try NSJSONSerialization.dataWithJSONObject(json, options: .PrettyPrinted)
// create post request
let url = NSURL(string: "https://...appspot.com/_ah/api/activityendpoint/v1/activity")!
let request = NSMutableURLRequest(URL: url)
request.HTTPMethod = "POST"
// 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)
}
Swift 5 answer:
let json: [String: Any] = ["key": "value"]
let jsonData = try? JSONSerialization.data(withJSONObject: json)
// create post request
let url = URL(string: "http://localhost:1337/postrequest/addData")! //PUT Your URL
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("\(String(describing: jsonData?.count))", forHTTPHeaderField: "Content-Length")
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
// insert json data to the request
request.httpBody = jsonData
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data, error == nil else {
print(error?.localizedDescription ?? "No data")
return
}
let responseJSON = try? JSONSerialization.jsonObject(with: data, options: [])
if let responseJSON = responseJSON as? [String: Any] {
print(responseJSON) //Code after Successfull POST Request
}
}
task.resume()
The following Swift 5 Playground code shows a possible way to solve your problem using JSONSerialization and URLSession:
import UIKit
import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true
let url = URL(string: "http://localhost:8080/new")!
let jsonDict = ["firstName": "Jane", "lastName": "Doe"]
let jsonData = try! JSONSerialization.data(withJSONObject: jsonDict, options: [])
var request = URLRequest(url: url)
request.httpMethod = "post"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpBody = jsonData
let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
if let error = error {
print("error:", error)
return
}
do {
guard let data = data else { return }
guard let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String: AnyObject] else { return }
print("json:", json)
} catch {
print("error:", error)
}
}
task.resume()
let url = URL(string: "url")!
var request = URLRequest(url: url)
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.setValue("application/json", forHTTPHeaderField: "Accept")
request.httpMethod = "POST"
let postString = "ChangeAccordingtoyourdata=\(paramOne)&ChangeAccordingtoyourdata2=\(paramTwo)"
request.httpBody = postString.data(using: .utf8)
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data, error == nil else { // check for fundamental networking error
print("error=\(error)")
return
}
if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 { // check for http errors
print("statusCode should be 200, but is \(httpStatus.statusCode)")
print("response = \(response)")
SVProgressHUD.showError(withStatus: "Request has not submitted successfully.\nPlease try after some time")
}
let responseString = String(data: data, encoding: .utf8)
print("responseString = \(responseString)")
SVProgressHUD.showSuccess(withStatus: "Request has submitted successfully.\nPlease wait for a while")
DispatchQueue.main.async {
// enter code
}
}
task.resume()
Perfect nRewik answer updated to 2019:
Make the dictionary:
let dic = [
"username":u,
"password":p,
"gems":g ]
Assemble it like this:
var jsonData:Data?
do {
jsonData = try JSONSerialization.data(
withJSONObject: dic,
options: .prettyPrinted)
} catch {
print(error.localizedDescription)
}
Create the request exactly like this, notice it is a "post"
let url = URL(string: "https://blah.com/server/dudes/decide/this")!
var request = URLRequest(url: url)
request.setValue("application/json; charset=utf-8",
forHTTPHeaderField: "Content-Type")
request.setValue("application/json; charset=utf-8",
forHTTPHeaderField: "Accept")
request.httpMethod = "POST"
request.httpBody = jsonData
Then send, checking for either a networking error (so, no bandwidth etc) or an error response from the server:
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data, error == nil else {
// check for fundamental networking error
print("fundamental networking error=\(error)")
return
}
if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 {
// check for http errors
print("statusCode should be 200, but is \(httpStatus.statusCode)")
print("response = \(response)")
}
let responseString = String(data: data, encoding: .utf8)
print("responseString = \(responseString)")
Fortunately it's now that easy.
you can do something like this:
func HTTPPostJSON(url: String, data: NSData,
callback: (String, String?) -> Void) {
var request = NSMutableURLRequest(URL: NSURL(string: url)!)
request.HTTPMethod = "POST"
request.addValue("application/json",forHTTPHeaderField: "Content-Type")
request.addValue("application/json",forHTTPHeaderField: "Accept")
request.HTTPBody = data
HTTPsendRequest(request, callback: callback)
}
func HTTPsendRequest(request: NSMutableURLRequest,
callback: (String, String?) -> Void) {
let task = NSURLSession.sharedSession()
.dataTaskWithRequest(request) {
(data, response, error) -> Void in
if (error != nil) {
callback("", error.localizedDescription)
} else {
callback(NSString(data: data,
encoding: NSUTF8StringEncoding)! as String, nil)
}
}
task.resume()
}
//use
var data :Dictionary<String, AnyObject> = yourDictionaryData<--
var requestNSData:NSData = NSJSONSerialization.dataWithJSONObject(request, options:NSJSONWritingOptions(0), error: &err)!
HTTPPostJSON("http://yourPosturl..", data: requestNSData) { (response, error) -> Void in
if error != nil{
//error
return;
}
println(response);
}
Swift4 - Apple Solution "POST" and "Codable"
Uploading Data to a Website using request.httpmethod = "Post" and Codable Stucts:
#see: Listing 2 Configuring a URL request
let userlogin = User(username: username, password: password, deviceid:UIDevice.current.identifierForVendor!.uuidString)
guard let uploadData = try? JSONEncoder().encode(userlogin) else {
print("Error UploadData: ")
return
}
let urlUser = URL(string: APPURL.apiURL)!
var request = URLRequest(url: urlUser)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
var responseStatus = 0
let task = URLSession.shared.uploadTask(with: request, from: uploadData) { data, response, error in
if let error = error {
let code = (error as NSError).code
print("Error:\(code) : \(error.localizedDescription)")
completion(code)
return
}
guard let response = response as? HTTPURLResponse else {
print("Invalid response")
return
}
// do your response handling here ...
No library required, simply use URLSession
here is an example:
let sampleData = ["key": "Value"]
var urlRequest = URLRequest(url: URL(string: "https://REPLACE.ME")!)
let urlSession = URLSession = URLSession(configuration: .default)
let encoder = JSONEncoder()
// inside a throwing function or wrap it in a doCatch block
let jsonData = try encoder.encode(sampleData)
urlRequest.httpMethod = "POST"
urlRequest.addValue("application/json",forHTTPHeaderField: "Content-Type")
urlRequest.httpBody = jsonData
let task = urlSession.dataTask(with: urlRequest) { data, response, error in
let statusCode = (response as? HTTPURLResponse)?.statusCode
print("💁🏻♂️ \(statusCode)")
}
task.resume()
A combination of several answers found in my attempt to not use 3rd party frameworks like Alamofire:
let body: [String: Any] = ["provider": "Google", "email": "emailaddress#gmail.com"]
let api_url = "https://erics.es/p/u"
let url = URL(string: api_url)!
var request = URLRequest(url: url)
do {
let jsonData = try JSONSerialization.data(withJSONObject: body, options: .prettyPrinted)
request.httpBody = jsonData
} catch let e {
print(e)
}
request.httpMethod = HTTPMethod.post.rawValue
request.addValue("application/json", 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
}
let responseJSON = try? JSONSerialization.jsonObject(with: data, options: [])
if let responseJSON = responseJSON as? [String: Any] {
print(responseJSON)
}
}
task.resume()
var request = URLRequest(url: URL(string: "http://yogpande.apphb.com/api/my/posttblhouse")!)
request.httpMethod = "POST"
let postString = "email=testname#gmail.com&password=1234567"
request.httpBody = postString.data(using: .utf8)
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data, error == nil else {
print("error=(error)")
return
}
if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 {
print("statusCode should be 200, but is \(httpStatus.statusCode)")
print("response = \(response)")
}
let responseString = String(data: data, encoding: .utf8)
print("responseString = \(responseString)")
}
task.resume()
}
For a Codable / Encodable type in Swift 4+
Use a JSONEncoder to transform the object into Data:
let jsonObject = ... // Encodable or Codable
guard let jsonData = try? JSONEncoder().encode(jsonObject) else {
fatalError("encoding error")
}
Then set that encoded object as the httpBody of the URLRequest:
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpBody = jsonData
Swift 5.5
As of Swift 5.5, we now have another alternative using async/await:
// Form the POST request:
let url = URL(string: "http://example.com/login")!
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
// Use the async variant of URLSession to make an HTTP POST request:
let (data, response) = try await URLSession.shared.upload(for: request, from: requestData)
Complete example:
struct LoginResponse: Decodable {
let id: String
let name: String
}
func login(_ username: String, _ password: String) async throws -> LoginResponse {
struct RequestData: Encodable {
let username: String
let password: String
}
// Encode data to JSON to send in the POST request body:
let encoder = JSONEncoder()
let requestData = try encoder.encode(RequestData(username: username, password: password))
// Form the POST request:
let url = URL(string: "http://example.com/login")!
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
// Use the async variant of URLSession to make an HTTP POST request:
let (data, response) = try await URLSession.shared.upload(for: request, from: requestData)
print("HTTPURLResponse:", response)
print("The response body is:", String(decoding: data, as: UTF8.self))
// Parse the JSON response:
return try JSONDecoder().decode(LoginResponse.self, from: data)
}
Usage
You must call it in an async context (so you can await it). One way is using a Task:
Task {
do {
let loginResponse = try await login("user1", "mypassword")
print("Login successful for user with id:", loginResponse.id)
} catch {
print(error)
}
}
// prepare json data
let mapDict = [ "1":"First", "2":"Second"]
let json = [ "title":"ABC" , "dict": mapDict ] as [String : Any]
let jsonData : NSData = NSKeyedArchiver.archivedData(withRootObject: json) as NSData
// create post request
let url = NSURL(string: "http://httpbin.org/post")!
let request = NSMutableURLRequest(url: url as URL)
request.httpMethod = "POST"
// insert json data to the request
request.httpBody = jsonData as Data
let task = URLSession.shared.dataTask(with: request as URLRequest){ data,response,error in
if error != nil{
return
}
do {
let result = try JSONSerialization.jsonObject(with: data!, options: []) as? [String:AnyObject]
print("Result",result!)
} catch {
print("Error -> \(error)")
}
}
task.resume()
var request = URLRequest(url: URL(string: "your URL")!)
request.httpMethod = "POST"
let postString = String(format: "email=%#&lang=%#", arguments: [txt_emailVirify.text!, language!])
print(postString)
emailString = txt_emailVirify.text!
request.httpBody = postString.data(using: .utf8)
request.addValue("delta141forceSEAL8PARA9MARCOSBRAHMOS", forHTTPHeaderField: "Authorization")
request.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data, error == nil
else
{
print("error=\(String(describing: error))")
return
}
do
{
let dictionary = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as! NSDictionary
print(dictionary)
let status = dictionary.value(forKey: "status") as! String
let sts = Int(status)
DispatchQueue.main.async()
{
if sts == 200
{
print(dictionary)
}
else
{
self.alertMessageOk(title: self.Alert!, message: dictionary.value(forKey: "message") as! String)
}
}
}
catch
{
print(error)
}
}
task.resume()
func function()
{
var parameters = [String:String]()
let apiToken = "Bearer \(ApiUtillity.sharedInstance.getUserData(key: "vAuthToken"))"
let headers = ["Vauthtoken":apiToken]
parameters = ["firstname":name,"lastname":last_name,"mobile":mobile_number,"email":emails_Address]
Alamofire.request(ApiUtillity.sharedInstance.API(Join: "user/edit_profile"), method: .post, parameters: parameters, encoding: URLEncoding.default,headers:headers).responseJSON { response in
debugPrint(response)
if let json = response.result.value {
let dict:NSDictionary = (json as? NSDictionary)!
print(dict)
// print(response)
let StatusCode = dict.value(forKey: "status") as! Int
if StatusCode==200
{
ApiUtillity.sharedInstance.dismissSVProgressHUDWithSuccess(success: "Success")
let UserData = dict.value(forKey: "data") as! NSDictionary
print(UserData)
}
else if StatusCode==401
{
let ErrorDic:NSDictionary = dict.value(forKey: "message") as! NSDictionary
let ErrorMessage = ErrorDic.value(forKey: "error") as! String
}
else
{
let ErrorDic:NSDictionary = dict.value(forKey: "message") as! NSDictionary
let ErrorMessage = ErrorDic.value(forKey: "error") as! String
}
}
else
{
ApiUtillity.sharedInstance.dismissSVProgressHUDWithError(error: "Something went wrong")
}
}
I am trying to parse JSON but getting this error:
type of expression is ambiguous without more context
My code is:
func jsonParser() {
let urlPath = "http://headers.jsontest.com/"
let endpoint = NSURL(string: urlPath)
let request = NSMutableURLRequest(URL:endpoint!)
let session = NSURLSession.sharedSession()
NSURLSession.sharedSession().dataTaskWithRequest(request){ (data, response, error) throws -> Void in
if error != nil {
print("Get Error")
}else{
//var error:NSError?
do {
let json:AnyObject = try NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions(rawValue: 0)) as? NSDictionary
print(json)
} catch let error as NSError {
// error handling
print(error?.localizedDescription)
}
}
}
//task.resume()
}
This is working fine with out try catch in Xcode 6.4 but this is not working in Xcode 7.
Don't declare an AnyObject type for your decoded object since you want it to be an NSDictionary and you're performing a conversion to do this.
Also it's better to use zero options for NSJSONSerialization instead of random ones.
In my example I've also used a custom error type just for demonstration.
Note, if you're using a custom error type, you have to also include a generic catch to be exhaustive (in this example, with a simple downcasting to NSError).
enum JSONError: String, ErrorType {
case NoData = "ERROR: no data"
case ConversionFailed = "ERROR: conversion from JSON failed"
}
func jsonParser() {
let urlPath = "http://headers.jsontest.com/"
guard let endpoint = NSURL(string: urlPath) else {
print("Error creating endpoint")
return
}
let request = NSMutableURLRequest(URL:endpoint)
NSURLSession.sharedSession().dataTaskWithRequest(request) { (data, response, error) in
do {
guard let data = data else {
throw JSONError.NoData
}
guard let json = try NSJSONSerialization.JSONObjectWithData(data, options: []) as? NSDictionary else {
throw JSONError.ConversionFailed
}
print(json)
} catch let error as JSONError {
print(error.rawValue)
} catch let error as NSError {
print(error.debugDescription)
}
}.resume()
}
The same with Swift 3.0.2:
enum JSONError: String, Error {
case NoData = "ERROR: no data"
case ConversionFailed = "ERROR: conversion from JSON failed"
}
func jsonParser() {
let urlPath = "http://headers.jsontest.com/"
guard let endpoint = URL(string: urlPath) else {
print("Error creating endpoint")
return
}
URLSession.shared.dataTask(with: endpoint) { (data, response, error) in
do {
guard let data = data else {
throw JSONError.NoData
}
guard let json = try JSONSerialization.jsonObject(with: data, options: []) as? NSDictionary else {
throw JSONError.ConversionFailed
}
print(json)
} catch let error as JSONError {
print(error.rawValue)
} catch let error as NSError {
print(error.debugDescription)
}
}.resume()
}
Apple declare here.
func dataTaskWithRequest(request: NSURLRequest, completionHandler: (NSData?, NSURLResponse?, NSError?) -> Void) -> NSURLSessionDataTask
Fix it:
NSURLSession.sharedSession().dataTaskWithRequest(request) { (data, response, error) -> Void in
// Your handle response here!
}
UPDATE:
func jsonParser() {
let urlPath = "http://headers.jsontest.com/"
let endpoint = NSURL(string: urlPath)
let request = NSMutableURLRequest(URL:endpoint!)
NSURLSession.sharedSession().dataTaskWithRequest(request) { (data, response, error) -> Void in
print(error)
}.resume()
}
RESULT:
Optional(Error Domain=NSURLErrorDomain Code=-1022 "The resource could not be loaded because the App Transport Security policy requires the use of a secure connection." UserInfo={NSUnderlyingError=0x7f8873f148d0 {Error Domain=kCFErrorDomainCFNetwork Code=-1022 "(null)"}, NSErrorFailingURLStringKey=http://headers.jsontest.com/, NSErrorFailingURLKey=http://headers.jsontest.com/, NSLocalizedDescription=The resource could not be loaded because the App >Transport Security policy requires the use of a secure connection.})
Hope this helps!
For Swift 4 Web service Call , Post Method using URLSession
func WebseviceCall(){
var request = URLRequest(url: URL(string: "YOUR_URL")!)
request.httpMethod = "POST"
let postString = "PARAMETERS"
request.httpBody = postString.data(using: .utf8)
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.setValue("application/json", forHTTPHeaderField: "Accept")
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data, error == nil else {
print("error=\(error)")
return
}
if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 {
print("statusCode should be 200, but is \(httpStatus.statusCode)")
print("response = \(response)")
}
do {
if let convertedJsonIntoDict = try JSONSerialization.jsonObject(with: data, options: []) as? NSDictionary {
// Print out dictionary
print(convertedJsonIntoDict)
}
} catch let error as NSError {
print(error.localizedDescription)
}
}
task.resume()
}
Here is the simplest way to parse JSON using NSUrlSession.,
let PARAMS = "{\"params1\":\"%#\",\"Params2\":\"%#\",\"params3\":\"%#\"}"
let URL = "your url here"
on submit button write this code.,
let urlStr = String(format: "%#",URL)
let jsonString = String(format:PARAMS, params1value,params2value,params3value )
// Encode your data here
let jsonData = jsonString.data(using:.utf8)
var request = URLRequest(url: URL(string: urlStr)!)
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.setValue("application/json", forHTTPHeaderField: "Accept")
//set your method type here
request.httpMethod = "POST"
request.httpBody = jsonData
let configuration = URLSessionConfiguration.default
// create a session here
let session = URLSession(configuration: configuration, delegate: nil, delegateQueue: OperationQueue.main)
let task = session.dataTask(with: request) {(data , response, error) in
if(error != nil){
print("Error \(String(describing: error))")
}
else {
do {
let fetchedDataDictionary = try JSONSerialization.jsonObject(with: data!, options: []) as? NSDictionary
print(fetchedDataDictionary!)
let message = fetchedDataDictionary?["response key here"] as! String
if message == "your response string" {
print(message)
}
else {
self.dataArray = (fetchedDataDictionary?["data"] as! NSArray)
}
}
catch let error as NSError {
print(error.debugDescription)
}
}
}
task.resume()
1)Make ApiConnection class in to your project..
import Foundation
class ApiConnection: NSObject {
class func postDataWithRequest(_ dicData:NSDictionary, completionHandler:#escaping (_ response:NSDictionary?,_ status:Bool)->Void)
{
let URL=Foundation.URL(string: Constant.API_URL)
let request=NSMutableURLRequest(url: URL!)
request.httpMethod="POST"
request.addValue(Constant.kApplicationJSON, forHTTPHeaderField:Constant.kContentType)
let data=try? JSONSerialization .data(withJSONObject: dicData, options: JSONSerialization.WritingOptions.prettyPrinted)
request.httpBody=data
//let dispatchTime = dispatch_time(DISPATCH_TIME_NOW, Int64(Double(NSEC_PER_SEC)*5))
//dispatch_after(dispatchTime, dispatch_get_main_queue()) {
let session = URLSession.shared.dataTask(with: request as URLRequest,completionHandler: { (data, response, error) in
if error==nil
{
DispatchQueue.main.async(execute: {
let dicResponse = try? JSONSerialization .jsonObject(with: data!, options: JSONSerialization.ReadingOptions.allowFragments) as! NSDictionary
completionHandler(dicResponse, error==nil)
})
}
else
{
completionHandler(nil, error==nil)
}
})
session.resume()
}
}
**********************************use this in your view controller****************
let dict : NSMutableDictionary = [:];
dict["Your key"] = "your value"
dict["Your key"] = "your value"
dict["Your key"] = "your value"
ApiConnection.postDataWithRequest(dict) { (response, status) in
if(status){
print(response);
else{
print("failed webservice call");
}
}
*************************************Swift3.0*************************************
var objDic = [String: Any]()
let dic = NSMutableDictionary()
print(dic)
objDic["action"] = ""
objDic["product_id"] = self.peroductid
// arrProduct .addObjects(from: objDic) as! Dictionary
print("\(objDic)")
Alamofire.request(Constant.Webservice_productinfo,
method: HTTPMethod.post,
parameters:objDic as? Parameters,
encoding: JSONEncoding.default,
headers: nil).responseJSON
{
(response:DataResponse<Any>) in
switch(response.result)
{
case .success(_):
if response.result.value != nil
{
let status = response2?.object(forKey: "status") as! String?
if status == "error"{}
//finding the status from response
var response2 = response.result.value as AnyObject?
self.response1 = response.result.value as! NSDictionary
let type =
(self.cartlistarray[0] as!NSDictionary)["base_image"]
cell.productname.text = (self.cartlistarray[0] as!NSDictionary)["name"] as? String
//Store the result value in swift 3.0
UserDefaults.standard.set(userDetail.value(forKey: "email") as? NSString, forKey: "email")
if(UserDefaults.standard.object(forKey:"email") == nil){}
//did select row click the data pass into another view
let ProductListViewController = self.storyboard?.instantiateViewController(withIdentifier: "ProductListViewController") as! ProductListViewController
ProductListViewController.category_id = ((self.bannerarry[0] as? [String : String])?["cat_id"])!
//or else callin from indexpath.row
item = ((cartlistarray[indexpath.row] as? NSDictionary)?.value(forKey:"product_id") as! String?)!
extension UIAlertController{
func showErrorAlert(strMesage:NSString,VC:Any)
{
let alert = UIAlertController(title: "Demo App", message: strMesage as String, preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.default, handler: nil))
(VC as AnyObject).present(alert, animated: true, completion: nil)
}
}
extension UILabel{
func setLabel(strTitle:String)
{
self.backgroundColor = UIColor.clear
self.textColor = UIColor.white
self.textAlignment = NSTextAlignment.left
self.font = UIFont(name: "Avenir-Light", size: 15.0)
self.font = UIFont.italicSystemFont(ofSize: 15)
self.text=strTitle
}
}
//image in to base 64
let image = imageCamera.image
let imageData:NSData = UIImageJPEGRepresentation(image!, 1.0)!as NSData
imageconvert = imageData.base64EncodedString(options: .lineLength64Characters)
base64formate = imageconvert.trimmingCharacters(in:CharacterSet.whitespaces)
print(base64formate)
print data into profle view
let imageurl:String! = SharedManager.sharedInstance().myMutableDict.value(forKey:"profileimg") as? String ?? "123"
let url = URL(string: imageurl)
DispatchQueue.global(qos: .userInitiated).async {
let imageData:NSData = NSData(contentsOf: url!)!
// When from background thread, UI needs to be updated on main_queue
DispatchQueue.main.async {
let image = UIImage(data: imageData as Data)
self.imageview.image = image
}
}
let actionSheetController: UIAlertController = UIAlertController(title: "Magento Extension App", message:response1?.object(forKey: "message") as? String, preferredStyle: .alert)
actionSheetController.addAction(UIAlertAction(title: "Ok", style: .default , handler:{ (UIAlertAction)in
print("Ok button click")
}))
self.present(actionSheetController, animated: true, completion: nil)
}
case .failure(_):
print("error: \(response.result.error)") // original
URL request
break
}
}
**************************objc**************************************************
NSDictionary *objDic1 = #{#"mode":#"loginUser",
#"email":[result
objectForKey:#"email"],
#"password":#"",
};
// With AFNetworking
AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc]initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
manager.requestSerializer = [AFJSONRequestSerializer serializer];
[manager.requestSerializer setTimeoutInterval:100];
// manager set
[manager.requestSerializer setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[manager POST:WEBSERVICE_CALL_URL parameters:objDic1 progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable result) {
[SVProgressHUD dismiss];
NSLog(#"This s my response %#",result);
NSLog(#"success!");
if ([[result valueForKey:kStatus] isEqualToString:kOK])
{
}
}
failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error)
{
}];
****************SDK LINK*******************************************
https://github.com/AFNetworking/AFNetworking
var userDetail = NSArray()
userDetail = self.response1.value(forKey: "userData") as! NSArray
print(userDetail)
self.tmpDic = userDetail[0] as! NSDictionary
print(self.tmpDic)
var optionsdic = NSDictionary()
optionsdic = self.tmpDic.value(forKey:"options") as! NSDictionary
print(optionsdic)
self.arrayOfKeys = optionsdic.allKeys as NSArray
print(self.arrayOfKeys)
if (self.arrayOfKeys.contains("color"))
{
print("color")
self.colorarray = optionsdic.value(forKey:"color") as! NSArray
print(self.colorarray.count)
for index in 0..<self.colorarray.count
{
var dic = NSDictionary ()
dic = self.colorarray .object(at: index) as! NSDictionary
self.colorarrayobject .add(dic)
print(dic)
}
print(self.colorarrayobject)
}
else {
var defaultarray = NSArray()
defaultarray = optionsdic.value(forKey:"default") as! NSArray
print(defaultarray)
self.element0array = defaultarray[0] as! NSArray
print(self.element0array)
self.dic = self.element0array[0] as! NSDictionary
print(dic)
self.arr5 = self.dic .value(forKey: "values") as! NSArray
print(self.arr5)
for iteams in 0..<self.arr5.count
{
var type = String()
type = ((self.arr5[iteams]as! NSDictionary)["label"]! as? String)!
self.configeresizeaarray.append(type)
}
print("default")
}
}
self.imagearray = self.array[0] as! NSArray
for items in 0..<self.imagearray.count
{
var type = String()
type = ((self.imagearray [items]as! NSDictionary)["image"]! as? String)!
self.cell0imagearray.append(type)
}
self.count = self.imagearray.count as Int
self.configurePageControl()
self.tableView.reloadData()
}
else
{
}
}
else
{
}