How to get cookie with URLSession request? - urlsession

I am sending one request using URLSession. I am getting the response but always value of HTTPCookieStorage.shared.cookies is 0 element. I am the testing in iOS simulator.
guard let url = URL(string: "https://10.10.224.30/sdc/v2/common/token") else {
return
}
let configuration = URLSessionConfiguration.default
configuration.httpCookieAcceptPolicy = .always
let mySession = URLSession(configuration: configuration, delegate: self, delegateQueue: nil)
var request = URLRequest(url: url)
request.setValue("OTT_CLIENT", forHTTPHeaderField: "User-Agent")
request.setValue("Basic aHR0cHdhdGNoOmY=", forHTTPHeaderField: "Authorization")
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.setValue("11044", forHTTPHeaderField: "X-Device-Identifier")
request.setValue("Deflate/gzip/compress",
forHTTPHeaderField: "Accept-Encoding")
request.setValue("application/json", forHTTPHeaderField: "Accept")
request.httpMethod = "POST"
var urlParser = URLComponents()
urlParser.queryItems = [
URLQueryItem(name: "scope", value: "OpenId ONEApp"),
URLQueryItem(name: "username", value: "2345679091"),
URLQueryItem(name: "grant_type", value: "password"),
URLQueryItem(name: "audience", value: "https://login.account.rakuten.com"),
URLQueryItem(name: "nonce", value: "a1b2c3")
]
let httpBodyString = urlParser.percentEncodedQuery
request.httpBody = httpBodyString?.data(using: String.Encoding.utf8)
let task = mySession.dataTask(with: request) { (data, response, error) in
if let httpResponse = response as? HTTPURLResponse {
let fields = httpResponse.allHeaderFields as! [String : String]
var cookies1 = URLSession.shared.configuration.httpCookieStorage?.cookies
print(cookies1)
}
task.resume()

You can do this by setting httpCookieStorage to any shared object or your object
let config = URLSessionConfiguration.default
config.httpCookieAcceptPolicy = .always
config.httpShouldSetCookies = true
config.httpCookieStorage = HTTPCookieStorage.shared
let mySession = URLSession(configuration: config, delegate: self, delegateQueue: nil)
Then in response, you can fetch
if let cookies = HTTPCookieStorage.shared.cookies(for: responseURL) {
print(cookies)
}
You will get cookie value.

Related

How to make signed API call in Swift

I am trying to do a signed API request with HMAC SHA256 signature.
How can I make the signed request? I am not able to generate the correct signature:
{"code":-1022,"msg":"Signature for this request is not valid."}
static func binanceAccountSnapshot(timeStamp: Int) {
let semaphore = DispatchSemaphore (value: 0)
let urlWithoutSignature = "https://api.binance.com/sapi/v1/capital/config/getall?timestamp=\(timeStamp)"
let secretString = "aN345refdcx78iygkhbrefdoyilhukB6prefd98uoixjk(api secret)"
let key = SymmetricKey(data: secretString.data(using: .utf8)!)
let signature = HMAC<SHA256>.authenticationCode(for: urlWithoutSignature.data(using: .utf8)!, using: key)
let signatureString = Data(signature).map { String(format: "%02hhx", $0) }.joined()
var request = URLRequest(url: URL(string: "https://api.binance.com/sapi/v1/capital/config/getall?timestamp=\(timeStamp)&signature=\(signatureString)")!,timeoutInterval: Double.infinity)
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("p4t98weflsudichjkxwtrfsduoxhckjnwe8isdokjx(api key)", forHTTPHeaderField: "X-MBX-APIKEY")
request.httpMethod = "GET"
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)!)
semaphore.signal()
}
task.resume()
}
Your code almost works, the string for the signature should only be the params for the url and not the whole url though (the string should only be those characters which come after the ? in the url)
static func binanceAccountSnapshot(timeStamp: Int) {
let semaphore = DispatchSemaphore (value: 0)
let params = timestamp=\(timeStamp)
let urlWithoutSignature = "https://api.binance.com/sapi/v1/capital/config/getall?\(params)"
let secretString = "aN345refdcx78iygkhbrefdoyilhukB6prefd98uoixjk(api secret)"
let key = SymmetricKey(data: secretString.data(using: .utf8)!)
let signature = HMAC<SHA256>.authenticationCode(for: params.data(using: .utf8)!, using: key)
let signatureString = Data(signature).map { String(format: "%02hhx", $0) }.joined()
var request = URLRequest(url: URL(string: "https://api.binance.com/sapi/v1/capital/config/getall?timestamp=\(timeStamp)&signature=\(signatureString)")!,timeoutInterval: Double.infinity)
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("p4t98weflsudichjkxwtrfsduoxhckjnwe8isdokjx(api key)", forHTTPHeaderField: "X-MBX-APIKEY")
request.httpMethod = "GET"
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)!)
semaphore.signal()
}
task.resume()
}

Borring SSl iOS 12

I am using simple json basic auth request to api but getting the error code
Xcode - 10.1 Beta
Swift 4
My Code
let username = "Api_Username"
let password = "Api_Password"
let loginString = String(format: "%#:%#", username, password)
let loginData = loginString.data(using: String.Encoding.utf8)!
let base64LoginString = loginData.base64EncodedString()
let request = NSMutableURLRequest(url: NSURL(string: "\(BaseUrl)\(taskUrl)")! as URL)
let session = URLSession.shared
request.httpMethod = method
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
request.setValue("Basic \(base64LoginString)", forHTTPHeaderField: "Authorization")
let task = session.dataTask(with: request as URLRequest, completionHandler: { data, response, error -> Void in
if error != nil {
print("Error: \(String(describing: error))")
} else {
print("Response: \(String(describing: response)) and data is \(data)")
print("status code is \(((response as? HTTPURLResponse)?.statusCode)!)")
do {
if let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSArray {
print("main array count is \(json.count)")
self.giftCardView?.responseofGiftCardApiCall(array: json, statusCode: ((response as? HTTPURLResponse)?.statusCode)!)
}
} catch {
print("error")
}
}
})
task.resume()
}
}
API response:-
new_protocol_boringssl_get_output_frames(1301) [C2.1:2][0x102788c30] get output frames failed, state 8196 thanks in advance

HTTP Authentication request with Campaign Monitor in Swift

I am trying to post user data to Campaign Monitor when they sign up in my app. Can anyone help me add the authorisation to the request. I currently get this error:
Optional("{\"Code\":50,\"Message\":\"Must supply a valid HTTP Basic
Authorization header\"}")
my code:
let parameters = [ "FirstName1": "test",
"SecondName": "test",
"email": "test#test.com"
]
let clientID = "52bb93ac4d9a3f261abcda0123456789"
let url = URL(string: "https://api.createsend.com/api/v3.2/clients.json")!
var request = URLRequest(url: url)
request.httpMethod = "Post"
do {
request.httpBody = try JSONSerialization.data(withJSONObject: parameters, options: .prettyPrinted)
} catch let error {
print(error.localizedDescription)
}
// add the API Key to the request / security
request.setValue(clientID, forHTTPHeaderField: "username") // IS THIS RIGHT??
// THiS WAS HOW I CREATED CORRECT AUTHORIZATION
let APIKey = "0069b38c27b3e44de0234567891011"
let listID = "5e61fde130969d561dc0234567891011"
let url = URL(string: "https://api.createsend.com/api/v3.2/subscribers/\(listID).json")!
var request = URLRequest(url: url)
request.httpMethod = "POST"
// add the API Key to the request / security
let loginString = "\(APIKey)"
let loginData = loginString.data(using: String.Encoding.utf8)
let base64LoginString = loginData!.base64EncodedString()
request.setValue("Basic \(base64LoginString)", forHTTPHeaderField: "Authorization")
do {
request.httpBody = try JSONSerialization.data(withJSONObject: parameters, options: .prettyPrinted)
} catch let error {
print(error.localizedDescription)
}
// THEN CAN SET UP THE SESSION
let session = URLSession(configuration: .default)
let task = session.dataTask(with: request) {
(data, response, error) in
if error != nil {
print("Error is: \(String(describing: error))")
}
if let response = response {
let nsHTTPResponse = response as! HTTPURLResponse
let statusCode = nsHTTPResponse.statusCode
print("status code = \(statusCode)")
}
if let data = data {
let postResponse = String(data: data, encoding: .utf8)
print("responseString = \(String(describing: postResponse))")
}
}
task.resume()
In this line:
// add the API Key to the request / security
request.setValue(clientID, forHTTPHeaderField: "username") // IS THIS RIGHT??
It's not correct, even they told you why. You need a Basic Auth Header
For POST requests in Swift, generally you have to set the following:
request.setValue("Basic " + clientID, forHTTPHeaderField: "Authorization") // is clientID your access token?
Good luck

Sending an image via POST in a Swift Playground

I try to send an image to the MS Cognitive Services Visions API in a Swift Playground.
The message I get as response is:
Response ["requestId": …, "code": InternalServerError, "message": Internal server error.]
Here is the code I use
let image = #imageLiteral(resourceName: "paper.jpg")
let imageData = UIImageJPEGRepresentation(image, 1)!
let endpoint = ("https://westeurope.api.cognitive.microsoft.com/vision/v1.0/analyze?visualFeatures=Description,Categories,Tags&subscription-key=\(subscriptionKey)")
let requestURL = URL(string: endpoint)!
let session = URLSession(configuration: URLSessionConfiguration.default)
var request:URLRequest = URLRequest(url: requestURL)
request.httpMethod = "POST"
// Image
let boundary = UUID().uuidString
request.addValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
var body = NSMutableData()
body.append("\r\n--\(boundary)\r\n".data(using: .utf8)!)
body.append("Content-Disposition: form-data; name=\"file\"; filename=\"image.jpg\"\\r\n".data(using: .utf8)!)
body.append("Content-Type: application/octet-stream\r\n\r\n".data(using: .utf8)!)
body.append(imageData)
body.append("\r\n--\(boundary)\r\n".data(using: .utf8)!)
request.httpBody = body as Data
let task = session.dataTask(with: request) { (data, response, error) in
guard let data = data, error == nil else { return }
do {
let json = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as! [String:Any]
print("Response \(json)")
} catch let error as Error {
print("Error \(error)")
}
}
task.resume()
I suspect I am not sending the image correctly. Any ideas?
It's probably best to not bother with a multi-part MIME, especially when you consider that the other Cognitive Service properties (namely Face and Emotion) don't support it.
let subscriptionKey = "YOUR-KEY"
let image = #imageLiteral(resourceName:"monkey.jpg")
let imageData = UIImageJPEGRepresentation(image, 1.0)!
let endpoint = ("https://westus.api.cognitive.microsoft.com/vision/v1.0/analyze?visualFeatures=Description,Categories,Tags")
let requestURL = URL(string: endpoint)!
let session = URLSession(configuration: URLSessionConfiguration.default)
var request:URLRequest = URLRequest(url: requestURL)
request.httpMethod = "POST"
request.addValue("application/octet-stream", forHTTPHeaderField: "Content-Type")
request.addValue(subscriptionKey, forHTTPHeaderField: "Ocp-Apim-Subscription-Key")
request.httpBody = imageData
var semaphore = DispatchSemaphore.init(value: 0);
let task = session.dataTask(with: request) { (data, response, error) in
guard let data = data, error == nil else { return }
do {
let json = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as! [String:Any]
print("Response \(json)")
} catch let error as Error {
print("Error \(error)")
}
semaphore.signal()
}
task.resume()
semaphore.wait()

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