How to create function for POST JSON parsing in Swift - json

In my project i have all POST method JSON URL's, so i need to create one separate function.. Now I want to use that function in all viewcontrollers with differnt urls and parameters... but i am unable to create separate function for JSON
I am writing same code for all viewcontrollrs with different urls and jsonpostParameters like below
func loginService(){
let url = URL(string: "https://e/api/login")!
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
let jsonpostParameters = LoginData(jsonrpc: "2.0", params: (PostLogin(email: nameTf.text!, password: passwordTf.text!, device_id: "2")))
do {
let jsonBody = try JSONEncoder().encode(jsonpostParameters)
request.httpBody = jsonBody
} catch {
print("Error while encoding parameter: \(error)")
}
let session = URLSession.shared
let task = session.dataTask(with: request) { [self] (data, response, error) in
guard let data = data else {return}
do{
let jsonModel = try JSONDecoder().decode(Employees.self, from: data)
print("new model \(jsonModel.result)")
DispatchQueue.main.sync{
if jsonModel.error != nil{
let controller = UIAlertController(title: "Alert", message: "Your email is not verified", preferredStyle: .alert)
let ok = UIAlertAction(title: "OK", style: .default, handler: nil)
let cancel = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
controller.addAction(ok)
controller.addAction(cancel)
self.present(controller, animated: true, completion: nil)
}
else{
let vc = UIStoryboard.init(name: "Main", bundle: Bundle.main).instantiateViewController(withIdentifier: "ProfileViewController") as? ProfileViewController
vc?.userData = jsonModel
vc?.tokenKey = jsonModel.result!.token
self.navigationController?.pushViewController(vc!, animated: true)
}
}
print("the error is \(error)")
}catch{ print("Error while decoding: \(error.localizedDescription)") }
}
task.resume()
}
how to write all code in one function with different urls and different jsonpostParameters to call that function in all view controllers, pls do help with code

class NetworkService: NSObject{
static let manager = NetworkService()
func loginService(_ urlPath: String, _ params: [String: Any]?, method: String, successBlock onSuccess: #escaping ((Your result model) -> Void),
failureBlock onFailure: #escaping ((Error) -> Void)){
guard let url = URL(string: urlPath) else {
return
}
var request = URLRequest(url: url)
request.httpMethod = method
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
let task = session.dataTask(with: request) { [self] (data, response, error) in
guard let data = data else {return}
if success{
onSuccess(pass data to VC)
}else{
onFailure(pass error)
}
}
task.resume
}
}
Call the service from Viewcontroller like
NetworkService.manager. loginService(urlPath, nil, method: "POST") { (success) in
//success code here
} failureBlock: { (failure) in
//Handle failure
}

Related

Passing data to the next POST request from that was fetched in the previous one [Swift / SwiftUI]

I am looking for a way how to pass further data that was received in the previous POST request. Below is my code.
Actual result: authtoken and sms_id become an empty String.
Some clarifications: The second POST request is called in the next screen in the sequence when the first is completed. TIA.
import SwiftUI
import Combine
enum APIError: Error {
case responseProblem
case decodingProblem
case encodingProblem
}
class NetworkService: ObservableObject {
#Published var user: UserRegisterRequest?
#Published var userRegistered: UserRegistered?
let uuid = UIDevice.current.identifierForVendor?.uuidString
let appid = "com.website.me"
var authToken = ""
var sms_id = ""
func postPhoneValidation(_ phone: String, completion: #escaping (Result<UserRegisterRequest, APIError>) -> Void) {
do {
guard let url = URL(string: APIRequests.postPhoneValidation) else { fatalError() }
let body: [String: Any] = ["phone" : phone]
let finalBody = try JSONSerialization.data(withJSONObject: body)
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.httpBody = finalBody
request.setValue(uuid, forHTTPHeaderField: "X-AUTH-Device")
request.setValue(appid, forHTTPHeaderField: "X-AUTH-AppID")
URLSession.shared.dataTask(with: request) { data, response, _ in
guard let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode == 200,
let jsondata = data else {
completion(.failure(.responseProblem))
return
}
do {
let validatedPhoneDictionary = try JSONDecoder().decode(UserRegisterRequest.self, from: jsondata)
self.authToken = validatedPhoneDictionary.auth_token
self.sms_id = validatedPhoneDictionary.sms_id
completion(.success(validatedPhoneDictionary))
print(validatedPhoneDictionary)
} catch {
completion(.failure(.decodingProblem))
}
}
.resume()
} catch {
completion(.failure(.encodingProblem))
}
}
func postSignUp(_ otpSms: String, completion: #escaping (Result<UserRegistered, APIError>) -> Void) {
do {
guard let url = URL(string: APIRequests.postSignUp) else { fatalError() }
let body : [String: Any] = ["otpSms" : otpSms, "sms_id" : self.sms_id]
let finalBody = try! JSONSerialization.data(withJSONObject: body)
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.httpBody = finalBody
request.setValue(uuid, forHTTPHeaderField: "X-AUTH-Device")
request.setValue(appid, forHTTPHeaderField: "X-AUTH-AppID")
request.setValue(self.authToken, forHTTPHeaderField: "X-AUTH-Token")
URLSession.shared.dataTask(with: request) { data, response, _ in
guard let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode == 200,
let jsondata = data else {
completion(.failure(.responseProblem))
return
}
do {
let registeredUser = try JSONDecoder().decode(UserRegistered.self, from: jsondata)
completion(.success(registeredUser))
print(registeredUser)
} catch {
completion(.failure(.decodingProblem))
}
}
.resume()
}
}
}
The reason for my problem was the moment that in view where I call the second method I've created a new instance of NetworkService instead of access it as ObservedObject. When I've changed it the problem was solved. –

how to make HTTPRequest with json in swift

I am making an ios application. I am new to swift and not able to understand my code. can anyone please help me to understand what is going on with my code.
This is login application on adding email id if the email exist it should go to next view controller and if not then it should give error. I am getting difficulty in understanding my code .
Here is my code:
class checkLoginViewController: UIViewController {
#IBOutlet weak var checkUsernametextfield: UITextField!
#IBAction func checkUsernameButton(_ sender: UIButton) {
print("Clicked On SUbmit !!!!")
//Read Value from Text
let email = checkUsernametextfield.text
let myUrl = URL(string: "http://192.168.0.117/rest/signup.php");
var request = URLRequest(url:myUrl!)
request.httpMethod = "POST"// Compose a query string
let postString = "email=\(String(describing: email))";
request.httpBody = postString.data(using: String.Encoding.utf8);
let task = URLSession.shared.dataTask(with: request) { (data: Data?, response: URLResponse?, error: Error?) in
if error != nil
{
print("error=\(String(describing: error))")
return
}
// You can print out response object
print("response = \(String(describing: response))")
//Let's convert response sent from a server side script to a NSDictionary object:
do {
let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSDictionary
if let parseJSON = json {
// Now we can access value of First Name by its key
let emailValue = parseJSON["email"] as? String
print("email: \(String(describing: emailValue))")
}
} catch {
print(error)
}
}
task.resume()
Output:
Clicked On SUbmit !!!! response = Optional( { URL: http://192.168.0.117/rest/signup.php } { Status
Code: 200, Headers {
Connection = (
"Keep-Alive"
);
"Content-Length" = (
61
);
"Content-Type" = (
"application/json"
);
Date = (
"Mon, 12 Mar 2018 06:35:58 GMT"
);
"Keep-Alive" = (
"timeout=5, max=100"
);
Server = (
"Apache/2.4.27 (Ubuntu)"
); } }) email: nil
Maybe try this. Hope it works.
let url = URL(string:"http://192.168.0.117/rest/signup.php")
let parameters = ["email": checkUsernametextfield.text]
var request = URLRequest(url : url!)
request.httpMethod = "POST"
request.httpBody = try? JSONSerialization.data(withJSONObject:parameters, options: [])
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
let session = URLSession.shared
session.dataTask(with: request, completionHandler: { (data, response, error) in
if let data = data {
do {
let json = try? JSONSerialization.jsonObject(with: data, options: []) as! Dictionary<String, Any>
if let json = json {
print("HERE SHOULD BE YOUR JSON \(json)")
}
}
} else {
print("Error \(String(describing: error?.localizedDescription))")
}
}).resume()
Here is way to send request.
enter code here
static func downloadConfig(url:URL, completion:#escaping (_ sucess:Bool , _ jsonObject: [String: String]?)->() ) {
var request = URLRequest(url: url)
request.setValue("application/x-www-form-urlencoded",
forHTTPHeaderField: "Content-Type")
request.httpMethod = "POST"
let postString = "id=13&name=Jack"
request.httpBody = postString.data(using: .utf8)
URLSession.shared.dataTask(with: request) { (data,response,error) in
if let data = data ,let httpURLResponse = response as? HTTPURLResponse, httpURLResponse.statusCode == 200 {
do {
if let todoJSON = try JSONSerialization.jsonObject(with: data, options: []) as? [String: String]{
completion(true,todoJSON)
}
else
{
completion(false,nil)
}
}
catch {
//erro parsing
completion(false,nil)
}
}
else
{
completion(false,nil)
}
}.resume()
}
use this download json function in this way.
//Download Json File
let base_url = "base_url"
let urlstr = String.init(format: "%#", base_url)
let url = URL(string: urlstr)
GameUtil.downloadConfig(url: url!) {
(sucess: Bool , jsonObject: [String:String]?) in
if sucess , jsonObject != nil
{
self.configJson = jsonObject!
}
}

How to send a POST request through Swift?

I have my controller like this -
def create
if (#user = User.find_by_email(params[:email])) && #user.valid_password?(params[:password])
render json: #user.as_json(only: [:email,:authentication_token]),status: :created
else
render json:('Unauthorized Access')
end
end
When I use Postman to make this request, I choose Body, and form data and adds in the email and password. And this WORKS
How to use swift to do the same? This is what I have tried
let url = URL(string: "http://localhost:3000/api/v1/user_serialized/")
let config = URLSessionConfiguration.default
let request = NSMutableURLRequest(url: url!)
request.httpMethod = "POST"
let bodyData = "email=Test#test.com&password=Test1234"
request.httpBody = bodyData.data(using: String.Encoding.utf8);
let session = URLSession(configuration: config)
let task = session.dataTask(with: url! as URL, completionHandler: {(data, response, error) in
let json = JSON(data:data!)
debugPrint(json)
})
task.resume()
I have made a Custom HTTP class where we can sent url, parameter and we will get Data from API. Below is the class.
import Foundation
//HTTP Methods
enum HttpMethod : String {
case GET
case POST
case DELETE
case PUT
}
class HttpClientApi: NSObject{
//TODO: remove app transport security arbitary constant from info.plist file once we get API's
var request : URLRequest?
var session : URLSession?
static func instance() -> HttpClientApi{
return HttpClientApi()
}
func makeAPICall(url: String,params: Dictionary<String, Any>?, method: HttpMethod, success:#escaping ( Data? ,HTTPURLResponse? , NSError? ) -> Void, failure: #escaping ( Data? ,HTTPURLResponse? , NSError? )-> Void) {
request = URLRequest(url: URL(string: url)!)
logging.print("URL = \(url)")
if let params = params {
let jsonData = try? JSONSerialization.data(withJSONObject: params, options: .prettyPrinted)
request?.setValue("application/json", forHTTPHeaderField: "Content-Type")
request?.httpBody = jsonData//?.base64EncodedData()
//paramString.data(using: String.Encoding.utf8)
}
request?.httpMethod = method.rawValue
let configuration = URLSessionConfiguration.default
configuration.timeoutIntervalForRequest = 30
configuration.timeoutIntervalForResource = 30
session = URLSession(configuration: configuration)
//session?.configuration.timeoutIntervalForResource = 5
//session?.configuration.timeoutIntervalForRequest = 5
session?.dataTask(with: request! as URLRequest) { (data, response, error) -> Void in
if let data = data {
if let response = response as? HTTPURLResponse, 200...299 ~= response.statusCode {
success(data , response , error as? NSError)
} else {
failure(data , response as? HTTPURLResponse, error as? NSError)
}
}else {
failure(data , response as? HTTPURLResponse, error as? NSError)
}
}.resume()
}
}
Now you can refer below code to get how to make an API call.
var paramsDictionary = [String:Any]()
paramsDictionary["username"] = "BBB"
paramsDictionary["password"] = "refef"
HttpClientApi.instance().makeAPICall(url: "Your URL", params:paramsDictionary, method: .POST, success: { (data, response, error) in
// API call is Successfull
}, failure: { (data, response, error) in
// API call Failure
})
I think you should pass your request instead of the url to session.dataTask
here is how my code looks like:
private let url = URL(string: "http://example.com/")!
func httpPost(jsonData: Data) {
if !jsonData.isEmpty {
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.httpBody = jsonData
URLSession.shared.getAllTasks { (openTasks: [URLSessionTask]) in
NSLog("open tasks: \(openTasks)")
}
let task = URLSession.shared.dataTask(with: request, completionHandler: { (responseData: Data?, response: URLResponse?, error: Error?) in
NSLog("\(response)")
})
task.resume()
}
}
Here is the Example of POST API for calling Login API with parameters "emailaddress" and "password" with userEmailID and Userpassword as two strings holding values for email and password respectively.
You can call this POST API anywhere in your view controller, as given below:
self.postLoginCall(url: "Your post method url") example: self.postLoginCall(url: "http://1.0.0.1/api/login.php")
func postLoginCall(url : String){
let request = NSMutableURLRequest(url: NSURL(string: url)! as URL)
request.httpMethod = "POST"
let postString = "emailaddress=\(userEmailID!)&password=\(Userpassword!)"
print(postString)
request.setValue("application/x-www-form-urlencoded; charset=utf-8", forHTTPHeaderField: "Content-Type")
request.httpBody = postString.data(using: String.Encoding.utf8)
let task = URLSession.shared.dataTask(with: request as URLRequest) { data, response, error in
guard error == nil && data != nil else { // check for fundamental networking error
print("error=\(error)")
return
}
do {
if let responseJSON = try JSONSerialization.jsonObject(with: data!) as? [String:AnyObject]{
print(responseJSON)
print(responseJSON["status"]!)
self.response1 = responseJSON["status"]! as! Int
print(self.response1)
//Check response from the sever
if self.response1 == 200
{
OperationQueue.main.addOperation {
//API call Successful and can perform other operatios
print("Login Successful")
}
}
else
{
OperationQueue.main.addOperation {
//API call failed and perform other operations
print("Login Failed")
}
}
}
}
catch {
print("Error -> \(error)")
}
}
task.resume()
}
Hello everyone I share below an example of a function to make a request in POST with SWIFT 5+.
This function allows you to send a POST request with an API entry point and parameters in the form of [[String: String]] and an Int to determine the output action.
For the output actions we call a function with Switch Case.
The operation is extremely simple. You have to put the two functions in one of your classes.
func MGSetRequestApi(endpoint: String, parameters: [[String: String]], MGSetAction: Int) -> String {
var setReturn: String!
let semaphore = DispatchSemaphore (value: 0)
var MGGetParam: String! = ""
for gate in parameters {
for (key, value) in gate {
let myParam = key + "=" + value + "&"
MGGetParam.append(contentsOf: myParam)
}
}
let postData = MGGetParam.data(using: .utf8)
var request = URLRequest(url: URL(string: endpoint)!,timeoutInterval: 10000)
request.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.httpMethod = "POST"
request.httpBody = postData
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data else {
print(String(describing: error))
semaphore.signal()
return
}
print(String(data: data, encoding: .utf8)!)
setReturn = String(data: data, encoding: .utf8)!
DispatchQueue.main.async {
self.MGRequestAction(MGGetIdRq: MGSetAction, MGGetData: setReturn)
}
semaphore.signal()
}
task.resume()
semaphore.wait()
return setReturn
}
Then implement this function to manage the outputs
func MGRequestAction(MGGetIdRq: Int, MGGetData: String) {
switch MGGetIdRq {
case 1:
// Do something here
case 2:
// Do something else here
case 3:
// Do something else here again
default:
print("Set default action");
}
}
How to use this, you have two possibilities, the first one is to process what the function
MGSetRequestApi(endpoint: String, parameters: [[String: String]], MGSetAction: Int) -> String
returns (String) or to pass by the function
MGRequestAction(MGGetIdRq: Int, MGGetData: String)
which will call your Json parse function.
The MGRequestAction() function takes for parameter an Int for the choice of the action and the String of the return of the request
Now to use it do like this:
_ = MGSetRequestApi(endpoint: MY_END_POINT_API,
parameters: [["KEY_1": "VALUE 1"],
["KEY_2": "VALUE 2"],
["KEY_3": "VALUE 3"],
["KEY_4": "VALUE 4"]],
MGSetAction: 3)

JSONObject vs JSONArray Swift

Im trying to do a PUSH HTTP Request and im getting an error describing that i need to supply a JSON Array and not a JSONObject, how do i create an Array from my single object, is it possible to do so?
func printdata(){
let myJsonDict: [String:AnyObject] = [
"action": "Websites",
"method":"school_webpage",
"tid":2,
"data":["schoolId":14273],
"type":"rpc"
]
do{
let jsonObject = try NSJSONSerialization.dataWithJSONObject(myJsonDict, options: NSJSONWritingOptions.PrettyPrinted)
HTTPPostJSON("http://wwww.oncoursesystems.com/json.axd/direct/router", data:jsonObject ) { (response, error) -> Void in
print(response);
}
}
catch{
}
}
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()
}
func HTTPPostJSON(url: String, data: NSData, callback: (String, String?) -> Void) {
let 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)
}
My method call
override func viewDidLoad() {
super.viewDidLoad()
searchController.searchResultsUpdater = self
searchController.hidesNavigationBarDuringPresentation = false
searchController.dimsBackgroundDuringPresentation = false
searchController.searchBar.sizeToFit()
definesPresentationContext = true
self.tableView.tableHeaderView = searchController.searchBar
names = HtmlController.loadData() as NSArray as! [String]
names.removeAtIndex(0)
clean()
refreshController = UIRefreshControl()
refreshController.addTarget(self, action: #selector(WebpageController.refresh(_:)), forControlEvents: UIControlEvents.ValueChanged)
self.tableView.addSubview(refreshController)
printdata()
// Uncomment the following line to preserve selection between presentations
// self.clearsSelectionOnViewWillAppear = false
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem()
}
Do you mean a POST request?
This works for me:
func HTTPPostJSON(url: String, data: AnyObject, callback: (String, String?) -> Void) {
let request = NSMutableURLRequest(URL: NSURL(string: url)!)
request.HTTPMethod = "POST"
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
request.HTTPBody = try! NSJSONSerialization.dataWithJSONObject(data, options: [])
HTTPsendRequest(request, callback: callback)
}
Note the method signature, pass your data as ["String": AnyObject] and handle the serialization inside the HTTPPostJSON method. I think part of what's wrong might be related to passing formatted json (when using the pretty options).
Edit:
Based on your comments, have you updated your print method to cater for the new method signature? it should be something along the lines of:
func printdata(){
let myJsonDict: [String:AnyObject] = [
"action": "Websites",
"method":"school_webpage",
"tid":2,
"data":["schoolId":14273],
"type":"rpc"]
HTTPPostJSON("http://wwww.oncoursesystems.com/json.axd/direct/router", data:myJsonDict) {
(response, error) -> Void in
print(response);
}
}

How to make HTTP Post request with JSON body in Swift?

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