How to Pass Key Value Parameter in JSON POST method in Swift? - ios

This is API http://itaag-env-1.ap-south-1.elasticbeanstalk.com/filter/taggedusers/
its parameter: "contactsList" : ["5987606147", "6179987671", "5082508888"]
its header: ["deviceid": "584D97F-761A-4C24-8C4B-C145A8B8BD75", "userType": "personal", "key": "9609cc826b0d472faf9967370c095c21"]
In my code if i put breakpoint then filtertaggedUser() is calling but i am unable to go inside completionHandler the access is not going inside dataTask
Access going to else part why? the api is working.
i am trying to pass parameter key value in URL string like below
let urlStr = "http://itaag-env-1.ap-south-1.elasticbeanstalk.com/filter/taggedusers/?contactsList=" + "8908908900"
is this correct approch?
code for above API:
func filtertaggedUser() {
print("inside filter taggedusers")
let headers = ["deviceid": "584D97F-761A-4C24-8C4B-C145A8B8BD75", "userType": "personal", "key": "9609cc826b0d472faf9967370c095c21"]
let urlStr = "http://itaag-env-1.ap-south-1.elasticbeanstalk.com/filter/taggedusers/?contactsList=" + "8908908900"
let request = NSMutableURLRequest(url: NSURL(string:urlStr)! as URL,cachePolicy: .useProtocolCachePolicy,timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
// access not coming here
let httpResponse = response as? HTTPURLResponse
if httpResponse!.statusCode == 200 {
print("filter taggedusers inside")
do {
print("filter taggedusers inside do")
let jsonObject = try JSONSerialization.jsonObject(with: data!, options: .mutableLeaves) as! [String :AnyObject]
print("filter taggedusers \(jsonObject)")
} catch { print(error.localizedDescription) }
} else { Constants.showAlertView(alertViewTitle: "", Message: "Something went wrong, Please try again", on: self) }
})
dataTask.resume()
}
OUTPUT:
POSTMAN OUTPUT
POSTMAN Body
why response is not coming, where i did mistake, please help me with the code.

We can call the Post request API like below,
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("584D97F-761A-4C24-8C4B-C145A8B8BD75", forHTTPHeaderField: "deviceid")
request.setValue("9609cc826b0d472faf9967370c095c21", forHTTPHeaderField: "key")
request.setValue("personal", forHTTPHeaderField: "userType")
let parameters = getPostString(params: ["contactsList":["8908908900"]])
request.httpBody = parameters.data(using: .utf8)
// Perform HTTP Request
let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
let httpResponse = response as? HTTPURLResponse
print(httpResponse!.statusCode)
// Check for Error
if let error = error {
print("Error took place \(error)")
return
}
// Convert HTTP Response Data to a String
if let data = data, let dataString = String(data: data, encoding: .utf8) {
print("Response data string:\n \(dataString)")
}
}
task.resume()
}
Output :
{"8908908900":{"userId":"9609cc826b0d472faf9967370c095c21","userName":"Satish Madhavarapu","profilePic":null,"oniTaag":true,"tagged":false,"userType":"personal"}}

Related

iOS: Sending push notification to firebase services via url request

I'm building an test app to send push notifications here is my code:
static func sendRequestPush(){
let json: [String: Any] = ["to": "key",
"priority": "high",
"notification": ["body":"Hello1", "title":"Hello world","sound":"default"]]
let urlStr:String = "https://fcm.googleapis.com/fcm/send"
let url = URL(string:urlStr)
let jsonData = try? JSONSerialization.data(withJSONObject: json)
var request = URLRequest(url: url!)
request.httpMethod = "POST"
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()
}
The problem is I don't get any response from googleapis neither the push notification. I get the push notification from dash board but not from my code.
Any of you knows what I'm doing wrong?
I'll really appreciate your help.
Try the below code, It works like charm :)
func sendRequestPush() {
// create the request
let url = URL(string: "https://fcm.googleapis.com/fcm/send")
let request = NSMutableURLRequest(url: url!)
request.httpMethod = "POST"
request.setValue("key=putYourLegacyServerKeyHere", forHTTPHeaderField: "authorization")
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
let parameters = ["to": "putYourFCMToken",
"priority": "high",
"notification": ["body":"Hello1", "title":"Hello world","sound":"default"]] as [String : Any]
do {
request.httpBody = try JSONSerialization.data(withJSONObject: parameters, options: .prettyPrinted) // pass dictionary to nsdata object and set it as request body
} catch let error {
print(error.localizedDescription)
}
let config = URLSessionConfiguration.default
let session = URLSession(configuration: config)
let dataTask = session.dataTask(with: request as URLRequest) { data,response,error in
let httpResponse = response as? HTTPURLResponse
if (error != nil) {
print(error!)
} else {
print(httpResponse!)
}
guard let responseData = data else {
print("Error: did not receive data")
return
}
do {
guard let responseDictionary = try JSONSerialization.jsonObject(with: responseData, options: [])
as? [String: Any] else {
print("error trying to convert data to JSON")
return
}
print("The responseDictionary is: " + responseDictionary.description)
} catch {
print("error trying to convert data to JSON")
return
}
DispatchQueue.main.async {
//Update your UI here
}
}
dataTask.resume()
}
"putYourLegacyServerKeyHere" change this according to your key that you can get in FCM Console
"putYourFCMToken" change this with the fcm token you got in didReceiveRegistrationToken (FCM Delegate)

Spotify API Authorization Error (Swift)

I've made a little App in Swift where a user can search the Spotify database for songs. I am using the Web API Console > Search for an Item. My problem is the new OAuth system where you have to sign-in and all that stuff. My authorization is ok, but when I'm trying to get an access token with the following code, it's returning me the following error: {"error":"server_error","error_description":"Unexpected status: 400"}. My code is:
let keys = "<MY_APPLICATION_KEYS>"
let url = NSURL(string: "https://accounts.spotify.com/api/token")
let session = URLSession.shared
let request = NSMutableURLRequest(url: url! as URL)
request.httpMethod = "POST"
request.setValue("Basic \(keys)", forHTTPHeaderField: "Authorization")
request.setValue("client_credentials", forHTTPHeaderField: "grant_type")
let task = session.dataTask(with: request as URLRequest) { (data, response, error) in
guard let _: Data = data, let _: URLResponse = response, error == nil else {
print(error!)
return
}
let dataString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
print("Data: \(dataString!)")
self.parseData(JSONData: data!)
}
task.resume()
}
var accessToken = ""
func parseData(JSONData : Data) {
do {
var readableJSON = try JSONSerialization.jsonObject(with: JSONData, options: .mutableContainers) as! JSONStandard
if let token = readableJSON["access_token"] as? String {
accessToken = token
}
print("Access Token: \(accessToken)")
updateTokenInFirebase()
}
catch{
print(error)
}
Any help would be very appreciated, thank you very much in advance!
Documentation of the Web API: Web API Link
I am using on the Client Credentials Flow the first method.
I know it's been ~1 year since you posted this but I had the same issue and after a few tries was able to get it. You can test this in Playground.
import Foundation
import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true
if let url = URL(string: "https://accounts.spotify.com/api/token") {
var postRequest = URLRequest(url: url)
postRequest.httpMethod = "POST"
let bodyParams = "grant_type=client_credentials"
postRequest.httpBody = bodyParams.data(using: String.Encoding.ascii, allowLossyConversion: true)
let id = "your client id"
let secret = "your secret"
let combined = "\(id):\(secret)"
let combo = "\(id):\(secret)".toBase64()
postRequest.addValue("Basic \(combo)", forHTTPHeaderField: "Authorization")
let task = URLSession.shared.dataTask(with: postRequest) { (data, response, error) in
guard let data = data else {
return
}
print(String(data: data, encoding: String.Encoding.utf8)!)
}
task.resume()
}
extension String {
func fromBase64() -> String? {
guard let data = Data(base64Encoded: self) else {
return nil
}
return String(data: data, encoding: .utf8)
}
func toBase64() -> String {
return Data(self.utf8).base64EncodedString()
}
}
I know this is really late, but the issue is with this line:
request.setValue("client_credentials", forHTTPHeaderField: "grant_type")
According to the authorization guide, this should be in the body of the request, not the headers.

How to send form data in POST request in Swift 3

I am trying to post form-data using webservice, userName & password, but in response it's showing an error stating "Could not connect to the server.".
Please help me to send form data in the POST request.
let dict:[String:String] = ["userName": userName as! String, "password": password as! String]
do {
let jsonData = try JSONSerialization.data(withJSONObject: dict, options: .prettyPrinted)
let url = URL(string: "(some url)")!
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("application/x-www-form-urlencoded charset=utf-8", forHTTPHeaderField: "Content-Type")
request.httpBody = jsonData
let task = URLSession.shared.dataTask(with: request) { data, response, error in
if error != nil {
print(error!.localizedDescription)
return
}
do {
let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSDictionary
if let parseJSON = json {
let resultValue:String = parseJSON["success"] as! String;
print("result: \(resultValue)")
print(parseJSON)
}
} catch let error as NSError {
print(error)
}
}
task.resume()
} catch {
print(error.localizedDescription)
}
I've tried adding values in the request, may be some values are missing in the request formed. Please help!
Thats the POSTMAN response
my calling api class
class ApiService
{
static func getPostString(params:[String:Any]) -> String
{
var data = [String]()
for(key, value) in params
{
data.append(key + "=\(value)")
}
return data.map { String($0) }.joined(separator: "&")
}
static func callPost(url:URL, params:[String:Any], finish: #escaping ((message:String, data:Data?)) -> Void)
{
var request = URLRequest(url: url)
request.httpMethod = "POST"
let postString = self.getPostString(params: params)
request.httpBody = postString.data(using: .utf8)
var result:(message:String, data:Data?) = (message: "Fail", data: nil)
let task = URLSession.shared.dataTask(with: request) { data, response, error in
if(error != nil)
{
result.message = "Fail Error not null : \(error.debugDescription)"
}
else
{
result.message = "Success"
result.data = data
}
finish(result)
}
task.resume()
}
}
and when use it
ApiService.callPost(url: url, params: params, finish: finishPost)
and the finish function
func finishPost (message:String, data:Data?) -> Void
{
do
{
if let jsonData = data
{
let parsedData = try JSONDecoder().decode(Response.self, from: jsonData)
print(parsedData)
}
}
catch
{
print("Parse Error: \(error)")
}
}

HTTP Request in Swift with POST method

I'm trying to run a HTTP Request in Swift, to POST 2 parameters to a URL.
Example:
Link: www.thisismylink.com/postName.php
Params:
id = 13
name = Jack
What is the simplest way to do that?
I don't even want to read the response. I just want to send that to perform changes on my database through a PHP file.
The key is that you want to:
set the httpMethod to POST;
optionally, set the Content-Type header, to specify how the request body was encoded, in case server might accept different types of requests;
optionally, set the Accept header, to request how the response body should be encoded, in case the server might generate different types of responses; and
set the httpBody to be properly encoded for the specific Content-Type; e.g. if application/x-www-form-urlencoded request, we need to percent-encode the body of the request.
E.g., in Swift 3 and later you can:
let url = URL(string: "https://httpbin.org/post")!
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 parameters: [String: Any] = [
"id": 13,
"name": "Jack & Jill"
]
request.httpBody = parameters.percentEncoded()
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard
let data = data,
let response = response as? HTTPURLResponse,
error == nil
else { // check for fundamental networking error
print("error", error ?? URLError(.badServerResponse))
return
}
guard (200 ... 299) ~= response.statusCode else { // check for http errors
print("statusCode should be 2xx, but is \(response.statusCode)")
print("response = \(response)")
return
}
// do whatever you want with the `data`, e.g.:
do {
let responseObject = try JSONDecoder().decode(ResponseObject<Foo>.self, from: data)
print(responseObject)
} catch {
print(error) // parsing error
if let responseString = String(data: data, encoding: .utf8) {
print("responseString = \(responseString)")
} else {
print("unable to parse response as string")
}
}
}
task.resume()
Where the following extensions facilitate the percent-encoding request body, converting a Swift Dictionary to a application/x-www-form-urlencoded formatted Data:
extension Dictionary {
func percentEncoded() -> Data? {
map { key, value in
let escapedKey = "\(key)".addingPercentEncoding(withAllowedCharacters: .urlQueryValueAllowed) ?? ""
let escapedValue = "\(value)".addingPercentEncoding(withAllowedCharacters: .urlQueryValueAllowed) ?? ""
return escapedKey + "=" + escapedValue
}
.joined(separator: "&")
.data(using: .utf8)
}
}
extension CharacterSet {
static let urlQueryValueAllowed: CharacterSet = {
let generalDelimitersToEncode = ":#[]#" // does not include "?" or "/" due to RFC 3986 - Section 3.4
let subDelimitersToEncode = "!$&'()*+,;="
var allowed: CharacterSet = .urlQueryAllowed
allowed.remove(charactersIn: "\(generalDelimitersToEncode)\(subDelimitersToEncode)")
return allowed
}()
}
And the following Decodable model objects facilitate the parsing of the application/json response using JSONDecoder:
// sample Decodable objects for https://httpbin.org
struct ResponseObject<T: Decodable>: Decodable {
let form: T // often the top level key is `data`, but in the case of https://httpbin.org, it echos the submission under the key `form`
}
struct Foo: Decodable {
let id: String
let name: String
}
This checks for both fundamental networking errors as well as high-level HTTP errors. This also properly percent escapes the parameters of the query.
Note, I used a name of Jack & Jill, to illustrate the proper x-www-form-urlencoded result of name=Jack%20%26%20Jill, which is “percent encoded” (i.e. the space is replaced with %20 and the & in the value is replaced with %26).
See previous revision of this answer for Swift 2 rendition.
Swift 4 and above
func postRequest() {
// declare the parameter as a dictionary that contains string as key and value combination. considering inputs are valid
let parameters: [String: Any] = ["id": 13, "name": "jack"]
// create the url with URL
let url = URL(string: "www.thisismylink.com/postName.php")! // change server url accordingly
// create the session object
let session = URLSession.shared
// now create the URLRequest object using the url object
var request = URLRequest(url: url)
request.httpMethod = "POST" //set http method as POST
// add headers for the request
request.addValue("application/json", forHTTPHeaderField: "Content-Type") // change as per server requirements
request.addValue("application/json", forHTTPHeaderField: "Accept")
do {
// convert parameters to Data and assign dictionary to httpBody of request
request.httpBody = try JSONSerialization.data(withJSONObject: parameters, options: .prettyPrinted)
} catch let error {
print(error.localizedDescription)
return
}
// create dataTask using the session object to send data to the server
let task = session.dataTask(with: request) { data, response, error in
if let error = error {
print("Post Request Error: \(error.localizedDescription)")
return
}
// ensure there is valid response code returned from this HTTP response
guard let httpResponse = response as? HTTPURLResponse,
(200...299).contains(httpResponse.statusCode)
else {
print("Invalid Response received from the server")
return
}
// ensure there is data returned
guard let responseData = data else {
print("nil Data received from the server")
return
}
do {
// create json object from data or use JSONDecoder to convert to Model stuct
if let jsonResponse = try JSONSerialization.jsonObject(with: responseData, options: .mutableContainers) as? [String: Any] {
print(jsonResponse)
// handle json response
} else {
print("data maybe corrupted or in wrong format")
throw URLError(.badServerResponse)
}
} catch let error {
print(error.localizedDescription)
}
}
// perform the task
task.resume()
}
For anyone looking for a clean way to encode a POST request in Swift 5.
You don’t need to deal with manually adding percent encoding.
Use URLComponents to create a GET request URL. Then use query property of that URL to get properly percent escaped query string.
let url = URL(string: "https://example.com")!
var components = URLComponents(url: url, resolvingAgainstBaseURL: false)!
components.queryItems = [
URLQueryItem(name: "key1", value: "NeedToEscape=And&"),
URLQueryItem(name: "key2", value: "vålüé")
]
let query = components.url!.query
The query will be a properly escaped string:
key1=NeedToEscape%3DAnd%26&key2=v%C3%A5l%C3%BC%C3%A9
Now you can create a request and use the query as HTTPBody:
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.httpBody = Data(query.utf8)
Now you can send the request.
Heres the method I used in my logging library: https://github.com/goktugyil/QorumLogs
This method fills html forms inside Google Forms.
var url = NSURL(string: urlstring)
var request = NSMutableURLRequest(URL: url!)
request.HTTPMethod = "POST"
request.setValue("application/x-www-form-urlencoded; charset=utf-8", forHTTPHeaderField: "Content-Type")
request.HTTPBody = postData.dataUsingEncoding(NSUTF8StringEncoding)
var connection = NSURLConnection(request: request, delegate: nil, startImmediately: true)
let session = URLSession.shared
let url = "http://...."
let request = NSMutableURLRequest(url: NSURL(string: url)! as URL)
request.httpMethod = "POST"
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
var params :[String: Any]?
params = ["Some_ID" : "111", "REQUEST" : "SOME_API_NAME"]
do{
request.httpBody = try JSONSerialization.data(withJSONObject: params, options: JSONSerialization.WritingOptions())
let task = session.dataTask(with: request as URLRequest as URLRequest, completionHandler: {(data, response, error) in
if let response = response {
let nsHTTPResponse = response as! HTTPURLResponse
let statusCode = nsHTTPResponse.statusCode
print ("status code = \(statusCode)")
}
if let error = error {
print ("\(error)")
}
if let data = data {
do{
let jsonResponse = try JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions())
print ("data = \(jsonResponse)")
}catch _ {
print ("OOps not good JSON formatted response")
}
}
})
task.resume()
}catch _ {
print ("Oops something happened buddy")
}
All the answers here use JSON objects. This gave us problems with the
$this->input->post()
methods of our Codeigniter controllers. The CI_Controller cannot read JSON directly.
We used this method to do it WITHOUT JSON
func postRequest() {
// Create url object
guard let url = URL(string: yourURL) else {return}
// Create the session object
let session = URLSession.shared
// Create the URLRequest object using the url object
var request = URLRequest(url: url)
// Set the request method. Important Do not set any other headers, like Content-Type
request.httpMethod = "POST" //set http method as POST
// Set parameters here. Replace with your own.
let postData = "param1_id=param1_value&param2_id=param2_value".data(using: .utf8)
request.httpBody = postData
// Create a task using the session object, to run and return completion handler
let webTask = session.dataTask(with: request, completionHandler: {data, response, error in
guard error == nil else {
print(error?.localizedDescription ?? "Response Error")
return
}
guard let serverData = data else {
print("server data error")
return
}
do {
if let requestJson = try JSONSerialization.jsonObject(with: serverData, options: .mutableContainers) as? [String: Any]{
print("Response: \(requestJson)")
}
} catch let responseError {
print("Serialisation in error in creating response body: \(responseError.localizedDescription)")
let message = String(bytes: serverData, encoding: .ascii)
print(message as Any)
}
// Run the task
webTask.resume()
}
Now your CI_Controller will be able to get param1 and param2 using $this->input->post('param1') and $this->input->post('param2')
#IBAction func btn_LogIn(sender: AnyObject) {
let request = NSMutableURLRequest(URL: NSURL(string: "http://demo.hackerkernel.com/ios_api/login.php")!)
request.HTTPMethod = "POST"
let postString = "email: test#test.com & password: testtest"
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)
let task = NSURLSession.sharedSession().dataTaskWithRequest(request){data, response, error in
guard error == nil && data != nil else{
print("error")
return
}
if let httpStatus = response as? NSHTTPURLResponse where httpStatus.statusCode != 200{
print("statusCode should be 200, but is \(httpStatus.statusCode)")
print("response = \(response)")
}
let responseString = String(data: data!, encoding: NSUTF8StringEncoding)
print("responseString = \(responseString)")
}
task.resume()
}

How do I perform GET and POST requests in Swift?

I adapted this from Ray Wenderlich's iOS Apprentice tutorial part 4.
This code works as a GET request sent to my Strongloop API with a simple database model, however:
This works, but I don't know why it works, since it invokes no method that I can see to actually send the request.
I see no means to make it into a POST request.
My question is: How do I perform a POST request? Is it done in a completely different way?
Let me know if you need more information.
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func getFromDB() {
let url = urlWithSearchText("")
println("URL: '\(url)'")
if let jsonString = performGetRequestWithURL(url) {
println("Received JSON string '\(jsonString)'")
}
}
func urlWithSearchText(searchText: String) -> NSURL {
let escapedSearchText = searchText.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)!
let urlString = String(format: "http://localhost:3000/api/Tests", escapedSearchText)
let url = NSURL(string: urlString)
return url!
}
func performGetRequestWithURL(url: NSURL) -> String? {
var error: NSError?
if let resultString = String(contentsOfURL: url, encoding: NSUTF8StringEncoding, error: &error) {
return resultString
} else if let error = error {
println("Download Error: \(error)")
} else {
println("Unknown Download Error")
}
return nil
}
Here is a picture of this working:
https://dl.dropboxusercontent.com/u/14464971/Images/Messages%20Image%281477993527%29.png
Swift 3 & above
GET
func getRequest() {
// request url
let url = URL(string: "https://jsonplaceholder.typicode.com/todos/1")! // change the url
// create URLSession with default configuration
let session = URLSession.shared
// create dataTask using the session object to send data to the server
let task = session.dataTask(with: url) { data, response, error in
if let error = error {
print("GET Request Error: \(error.localizedDescription)")
return
}
// ensure there is valid response code returned from this HTTP response
guard let httpResponse = response as? HTTPURLResponse,
(200...299).contains(httpResponse.statusCode) else {
print("Invalid Response received from the server")
return
}
// ensure there is data returned
guard let responseData = data else {
print("nil Data received from the server")
return
}
do {
// serialise the data object into Dictionary [String : Any]
if let jsonResponse = try JSONSerialization.jsonObject(with: responseData, options: .mutableContainers) as? [String: Any] {
print(jsonResponse)
} else {
print("data maybe corrupted or in wrong format")
throw URLError(.badServerResponse)
}
} catch let error {
print("JSON Parsing Error: \(error.localizedDescription)")
}
}
// resume the task
task.resume()
}
POST
func postRequest() {
// declare the parameter as a dictionary that contains string as key and value combination. considering inputs are valid
let parameters: [String: Any] = ["name": "abc", "password": "password#123"]
// create the url with URL
let url = URL(string: "http://myServerName.com/api")! //change the url
// create the session object
let session = URLSession.shared
// now create the URLRequest object using the url object
var request = URLRequest(url: url)
request.httpMethod = "POST" //set http method as POST
// add headers for the request
request.addValue("application/json", forHTTPHeaderField: "Content-Type") // change as per server requirements
request.addValue("application/json", forHTTPHeaderField: "Accept")
do {
// convert parameters to Data and assign dictionary to httpBody of request
request.httpBody = try JSONSerialization.data(withJSONObject: parameters, options: .prettyPrinted)
} catch let error {
print(error.localizedDescription)
return
}
// create dataTask using the session object to send data to the server
let task = session.dataTask(with: request) { data, response, error in
if let error = error {
print("Post Request Error: \(error.localizedDescription)")
return
}
// ensure there is valid response code returned from this HTTP response
guard let httpResponse = response as? HTTPURLResponse,
(200...299).contains(httpResponse.statusCode)
else {
print("Invalid Response received from the server")
return
}
// ensure there is data returned
guard let responseData = data else {
print("nil Data received from the server")
return
}
do {
// create json object from data or use JSONDecoder to convert to Model stuct
if let jsonResponse = try JSONSerialization.jsonObject(with: responseData, options: .mutableContainers) as? [String: Any] {
print(jsonResponse)
// handle json response
} else {
print("data maybe corrupted or in wrong format")
throw URLError(.badServerResponse)
}
} catch let error {
print(error.localizedDescription)
}
}
task.resume()
}
Below are two POST methods. Depending on if you want it synchronous (everything else waits until the post method is completed) or asynchronous (POST method runs in background, other methods run in parallel).
Methods
// POST data to url
func postDataAsynchronous(url: String, bodyData: String, completionHandler: (responseString: String!, error: NSError!) -> ()) {
var URL: NSURL = NSURL(string: url)!
var request:NSMutableURLRequest = NSMutableURLRequest(URL:URL)
request.HTTPMethod = "POST";
request.HTTPBody = bodyData.dataUsingEncoding(NSUTF8StringEncoding);
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue()){
response, data, error in
var output: String!
if data != nil {
output = NSString(data: data, encoding: NSUTF8StringEncoding) as! String
}
completionHandler(responseString: output, error: error)
}
}
// Obtain the data
func postDataSynchronous(url: String, bodyData: String, completionHandler: (responseString: String!, error: NSError!) -> ())
{
let URL: NSURL = NSURL(string: url)!
var request:NSMutableURLRequest = NSMutableURLRequest(URL:URL)
request.HTTPMethod = "POST"
request.HTTPBody = bodyData.dataUsingEncoding(NSUTF8StringEncoding);
request.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
var response: NSURLResponse?
var error: NSError?
// Send data
let data = NSURLConnection.sendSynchronousRequest(request, returningResponse: &response, error: &error)
var output: String! // Default to nil
if data != nil{
output = NSString(data: data!, encoding: NSUTF8StringEncoding) as! String
}
completionHandler(responseString: output, error: error)
}
Using them
You can then call (use) them like so:
postDataSynchronous(url, bodyData: bodyData) {
responseString, error in
if error != nil {
println("Error during post: \(error)")
return
}
else{
//Success
println(responseString)
userType = responseString // Set usertype based on server response
}
}
SWIFT 2.0
func postData(url: String, params: Dictionary<String, String>, completionHandler: (data: NSData?, response: NSURLResponse?, error: NSError?) -> ()) {
// Indicate download
UIApplication.sharedApplication().networkActivityIndicatorVisible = true
let url = NSURL(string: url)!
// print("URL: \(url)")
let request = NSMutableURLRequest(URL: url)
let session = NSURLSession.sharedSession()
request.HTTPMethod = "POST"
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
// Verify downloading data is allowed
do {
request.HTTPBody = try NSJSONSerialization.dataWithJSONObject(params, options: [])
} catch let error as NSError {
print("Error in request post: \(error)")
request.HTTPBody = nil
} catch {
print("Catch all error: \(error)")
}
// Post the data
let task = session.dataTaskWithRequest(request) { data, response, error in
completionHandler(data: data, response: response, error: error)
// Stop download indication
UIApplication.sharedApplication().networkActivityIndicatorVisible = false // Stop download indication
}
task.resume()
}
guard let url = URL(string: "https://jsonplaceholder.typicode.com/users") else { return }
let session = URLSession.shared
session.dataTask(with: url) { (data, response, error) in
if let response = response {
print(response)
}
if let data = data {
print(data)
do {
let json = try JSONSerialization.jsonObject(with: data, options: [])
print(json)
} catch {
print(error)
}
}
}.resume()
}
It's a get method.
This method invokes the http request.
String(contentsOfURL: url, encoding: NSUTF8StringEncoding, error: &error)
Because Swift String has no init signature like this.
This method would be written somewhere in the project, as extension of String
It would be something like this
extension String{
init(contentsOfURL: NSURL, encoding: NSUTF8StringEncoding, inout error: NSError){
// load data from url
self = //parse data to string
}
}
The String(contentsOfUrl:encoding:error) initializer makes a GET request under the hood and returns the content as a string with the specified encoding.
One way to make a request would be to create an NSURLConnection and use NSMutablrURLRequest set the HTTP method the post. With the NSMutableURLRequest, you can create a NSURLConnection and start it immediately with a delegate or you can call NSURLConnection.sendSynchronousRequest or NSURLConnection.sendAsynchronousRequest to send the request.
let parameters = ["username": "#Bipin_kumar", "tweet": "HelloWorld"]
guard let url = URL(string: "https://jsonplaceholder.typicode.com/posts") else { return }
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
guard let httpBody = try? JSONSerialization.data(withJSONObject: parameters, options: []) else { return }
request.httpBody = httpBody
let session = URLSession.shared
session.dataTask(with: request) { (data, response, error) in
if let response = response {
print(response)
}
if let data = data {
do {
let json = try JSONSerialization.jsonObject(with: data, options: [])
print(json)
} catch {
print(error)
}
}
}.resume()
It's a post method.
GET Request
func getRequest(with url: URL, callback: #escaping (Any?) -> Swift.Void) -> Void {
let defaultConfigObject = URLSessionConfiguration.default
defaultConfigObject.timeoutIntervalForRequest = 30.0
defaultConfigObject.timeoutIntervalForResource = 60.0
let session = URLSession.init(configuration: defaultConfigObject, delegate: nil, delegateQueue: nil)
var urlRequest = URLRequest(url: url as URL)
urlRequest.addValue("application/json", forHTTPHeaderField: "Content-Type")
urlRequest.httpMethod = "GET"
session.dataTask(with: urlRequest, completionHandler: { (data, response, error) in
guard let httpResponse: HTTPURLResponse = response as? HTTPURLResponse
else {
print("Error: did not receive data")
return
}
var response : (Any)? = nil
if httpResponse.statusCode == 200 {
print(httpResponse)
guard let responseData = data else {
print("Error: did not receive data")
return
}
do {
let responseData = try JSONSerialization.jsonObject(with: responseData, options: [JSONSerialization.ReadingOptions.allowFragments])
response = responseData
callback(response)
}
catch _ as NSError {
let responseString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
callback(responseString)
return
}
}
else {
print(httpResponse)
guard error == nil else {
print("error calling GET on /todos/1")
print(error ?? "error")
callback(response!)
return
}
}
}).resume()
}
POST REQUEST
//MARK: post request
func postRequest(with url:URL, postBody:String, callback: #escaping (Any?) -> Void) -> Void {
let defaultConfigObject = URLSessionConfiguration.default
defaultConfigObject.timeoutIntervalForRequest = 30.0
defaultConfigObject.timeoutIntervalForResource = 60.0
let session = URLSession.init(configuration: defaultConfigObject, delegate: nil, delegateQueue: nil)
let params: String! = postBody
var urlRequest = URLRequest(url: url as URL)
urlRequest.httpMethod = "POST"
let data = params.data(using: String.Encoding(rawValue: String.Encoding.utf8.rawValue))
urlRequest.httpBody = data
session.dataTask(with: urlRequest, completionHandler: { (data, urlResponse, error) in
guard let httpResponse:HTTPURLResponse = urlResponse as? HTTPURLResponse
else{
print("did not get any data")
return
}
var response : (Any)? = nil
if httpResponse.statusCode == 200 {
guard let responseData = data else {
print("Error: did not receive data")
return
}
do {
guard let responseData = try JSONSerialization.jsonObject(with: responseData, options: []) as? [String: AnyObject] else {
print("error trying to convert data to JSON")
return
}
response = responseData
callback(response)
} catch _ as NSError {
let responseString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
callback(responseString)
return
}
}
else {
guard error == nil else {
print("error calling GET on /todos/1")
print(error ?? "error")
callback(nil)
return
}
}
}).resume()
}
Always try to check the HTTPURLResponse code

Resources