This is how I am making an api request using URLSession:
let url = URL(string: "http://192.168.1.21.2/FeatureRequestComponent/FeatureRequestComponentAPI")!
var request = URLRequest(url: url)
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.httpMethod = "POST"
let parameters: [String: Any] = [
"AppID": "67B10F42-A372-4D4B-B630-5933E3F7FD65",
"FeatureTitle": "ABCD",
"UserName": "Ayaz",
"UserEmail": self.userEmailTextfield.text ?? "",
"Priority":"H",
"Description": self.featureDescriptionTextView.text ?? "",
"UseCase": self.useCaseTextView.text ?? "",
"DeviceType" : "iPhone"
]
request.httpBody = parameters.percentEscaped().data(using: .utf8)
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 ?? "Unknown error")
return
}
guard (200 ... 299) ~= response.statusCode else { // check for http errors
print("statusCode should be 2xx, but is \(response.statusCode)")
print("response = \(response)")
return
}
let responseString = String(data: data, encoding: .utf8)
print("responseString = \(responseString)")
}
task.resume()
}
extension Dictionary {
func percentEscaped() -> String {
return map { (key, value) in
let escapedKey = "\(key)".addingPercentEncoding(withAllowedCharacters: .urlQueryValueAllowed) ?? ""
let escapedValue = "\(value)".addingPercentEncoding(withAllowedCharacters: .urlQueryValueAllowed) ?? ""
return escapedKey + "=" + escapedValue
}
.joined(separator: "&")
}
}
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
}()
}
above I have given the extensions for percent escaped and a character set also
But the response I get is an error like this:
responseString = Optional("{\"isError\":true,\"ErrorMessage\":\"Unknown Error Occured\",\"Result\":{},\"ErrorCode\":999}")
What am I doing wrong here...? I'm supposed to get a success in my response but what I'm getting is the error message.
I tried to detect the problem in your code but I did not find it
use my code war it works well
I hope this helps you
let jsonData = try? JSONSerialization.data(withJSONObject: ["username":username,"password":password])
var request = URLRequest(url: URL(string: "http://api.com/login")!)
request.httpMethod = "POST";
request.addValue("application/json", forHTTPHeaderField: "Accept")
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
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 dataJSON = try? JSONSerialization.jsonObject(with: data, options: [])
if let responseJSON = dataJSON as? [String: Any] {
DispatchQueue.main.async {
let User = responseJSON["user"] as! [String:Any]
print("user: ", User)
print("name: ", User["name"]!)
print("email: ", User["email"]!)
}
}else {
print("error")
}
}
task.resume()
Related
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"}}
I am working on REST API's in iOS application.
I have tested Server URL and Parameters of POST method.
It is returning with
Your browser sent a request that this server could not understand
this error in response.
For the GET request API is working fine.
If anyone faced the same issue please let me know.
Thank you.
Please check my web service model
let configuration = URLSessionConfiguration.default;
let session = URLSession(configuration: configuration, delegate: nil, delegateQueue: nil)
var urlString = String()
urlString.append(Constant.BASE_URL)
urlString.append(methodName)
let encodedUrl = urlString.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed)
let serverUrl: URL = URL(string: (encodedUrl?.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed))!)!
var request : URLRequest = URLRequest(url: serverUrl, cachePolicy: .useProtocolCachePolicy, timeoutInterval: 60.0)
var paramStr : String = String()
if requestDict.count > 0 {
let keysArray = requestDict.keys
for key in keysArray {
if paramStr.isEmpty{
paramStr.append("\(key)=\(requestDict[key]! as! String)")
}else{
paramStr.append("&\(key)=\(requestDict[key]! as! String)")
}
}
}
let postData:Data = try! JSONSerialization.data(withJSONObject: requestDict)//paramStr.data(using: .utf8)!
let reqJSONStr = String(data: postData, encoding: .utf8)
let postLength = "\(postData.count)"
request.httpMethod = "POST"
request.setValue(postLength, forHTTPHeaderField: "Content-Length")
//request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
//request.httpBody = reqJSONStr?.data(using: .utf8)
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpBody = try! JSONSerialization.data(withJSONObject: requestDict)
if headerValue != nil{
let allkeys = headerValue.keys
for key in allkeys {
request.setValue(headerValue[key] as! String?, forHTTPHeaderField: key)
}
}
let postDataTask : URLSessionDataTask = session.dataTask(with: request, completionHandler:
{
data, response, error in
if data != nil && error == nil{
let res = String(data: data!, encoding: .utf8)
let dict = convertToDictionary(text: res!)
if let httpResponse = response as? HTTPURLResponse {
//print("error \(httpResponse.statusCode)")
if httpResponse.statusCode == 200
{
DispatchQueue.main.async {
successBlock (response!,(dict)!)
}
}
else
{
if (error?.localizedDescription) != nil
{
errorBlock((error?.localizedDescription)! as String)
}
else
{
errorBlock("")
}
}
}
else
{
errorBlock((error?.localizedDescription)! as String)
}
}
else{
if let httpResponse = error as? HTTPURLResponse {
//print("error \(httpResponse.statusCode)")
}
errorBlock((error?.localizedDescription)! as String)
}
})
postDataTask.resume()
Assuming that your backend is expecting an form-urlencoded request, then you should convert your parameters dictionary in an string url encoded
This is an example
let parameters : [String:Any] = ["ajax":1,"test":"abuela"]
var queryItems : [URLQueryItem] = []
for key in parameters.keys {
if let value = parameters[key] as? String {
queryItems.append(URLQueryItem(name: key, value: value))
}else{
queryItems.append(URLQueryItem(name: key, value: String(describing:parameters[key]!)))
}
}
var urlComponents = URLComponents()
urlComponents.queryItems = queryItems
then if you
print(urlComponents.percentEncodedQuery!)
you will get
test=abuela&ajax=1
then with this you need to add in your urlString
urlString.append("&" + urlComponents.percentEncodedQuery!)
FULL CODE
let configuration = URLSessionConfiguration.default;
let session = URLSession(configuration: configuration, delegate: nil, delegateQueue: nil)
var urlString = String()
urlString.append(Constant.BASE_URL)
urlString.append(methodName)
var queryItems : [URLQueryItem] = []
for key in parameters.keys {
if let value = parameters[key] as? String {
queryItems.append(URLQueryItem(name: key, value: value))
}else{
queryItems.append(URLQueryItem(name: key, value: String(describing:parameters[key]!)))
}
}
var urlComponents = URLComponents()
urlComponents.queryItems = queryItems
print(urlComponents.percentEncodedQuery!)
urlString.append("&" + urlComponents.percentEncodedQuery!)
let encodedUrl = urlString.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed)
let serverUrl: URL = URL(string: urlString)!
var request : URLRequest = URLRequest(url: serverUrl, cachePolicy: .useProtocolCachePolicy, timeoutInterval: 60.0)
request.httpMethod = "POST"
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
let postDataTask : URLSessionDataTask = session.dataTask(with: request, completionHandler:
{
data, response, error in
if data != nil && error == nil{
let res = String(data: data!, encoding: .utf8)
let dict = convertToDictionary(text: res!)
if let httpResponse = response as? HTTPURLResponse {
//print("error \(httpResponse.statusCode)")
if httpResponse.statusCode == 200
{
DispatchQueue.main.async {
successBlock (response!,(dict)!)
}
}
else
{
if (error?.localizedDescription) != nil
{
errorBlock((error?.localizedDescription)! as String)
}
else
{
errorBlock("")
}
}
}
else
{
errorBlock((error?.localizedDescription)! as String)
}
}
else{
if let httpResponse = error as? HTTPURLResponse {
//print("error \(httpResponse.statusCode)")
}
errorBlock((error?.localizedDescription)! as String)
}
})
postDataTask.resume()
IF your backend is waiting application/json http body encoded
You are passing an JSON object in the httpBody but your contentType header is wrong instead of "application/x-www-form-urlencoded" should be "application/json", I think your json convertion is wrong try using your requestDict directly and JSONSerialization will convert the dictionary in a valid JSON object that you can use in your request.httpBody
replace
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
by
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
Use this to convert to JSON your requestDict parameters dictionary
request.httpBody = try! JSONSerialization.data(withJSONObject: requestDict)
Here i got a token number from api like as shown here "210" and it is saving using userdefaults but when i tried to retrieve data from the userdefaults then it is returning "\"210\"" like this why it is adding slashes and quotes can anyone help me how to resolve this ?
here is the code for posting key
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("Bearer \(self.CustomerToken!)", forHTTPHeaderField: "Authorization")
print(self.CustomerToken!)
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=\(String(describing: 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 = \(String(describing: response))")
}
let responseString = String(data: data, encoding: .utf8)
print("responseString = \(responseString!)")
let status = (response as! HTTPURLResponse).statusCode
self.keyStatusCode = status
print(responseString!)
self.customerCartIdNumber = responseString!
self.customerCartIdNumber = responseString!
UserDefaults.standard.set(self.customerCartIdNumber, forKey: "CustomerLoginNumber")
print(self.customerCartIdNumber!)
print(responseString!)
here is the code for getting key
let customerId = UserDefaults.standard.string(forKey: "CustomerLoginNumber")
self.customerCartId = customerId!
print(customerId!)
here is the code for posting
func customerAddToCartItemsDownloadJsonWithURl(cartApi: String){
let url = URL(string: cartApi)
var request = URLRequest(url: url! as URL)
request.httpMethod = "POST"
let cartNumber = customerCartId?.replacingOccurrences(of: "\\", with: "")
let parameters : [String: Any] = ["cartItem":
[
"quote_id": "\(customerCartId!)",
"sku": "\(itemCode!)",
"qty":"1"
]
]
print(customerCartId)
print(parameters)
print(cartNumber)
do {
request.httpBody = try JSONSerialization.data(withJSONObject: parameters, options: .prettyPrinted)
} catch let error {
print(error.localizedDescription)
}
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("Bearer \(self.customerKeyToken!)", forHTTPHeaderField: "Authorization")
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data, error == nil else {
print("error=\(String(describing: error))")
return
}
if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 {
print("statusCode should be 200, but is \(httpStatus.statusCode)")
print("response = \(String(describing: response))")
}
let responseString = String(data: data, encoding: .utf8)
print("responseString = \(responseString!)")
}
task.resume()
}
I'm doing a very simple postRequest but I the service is not responding me, do you have any idea of why this is happening? maybe I'm doing something wrong could you help me? Thanks in advance.
Here is my code Request in postman
#IBAction func buton(_ sender: Any) {
let parameters = ["acceptPrivacyNotice": true, "name" :"xxxxx xxxxx", "email": "xxxxx#mail.com", "password":"Qwerty2012", "passwordConfirm":"Qwerty2012","deviceID" : "", "isProvider" : false, "idTypeProvider": 1] as [String : Any]
guard let url = URL(string: "https://www.apps-sellcom-dev.com/Engie/api/account/register") else {return}
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("M1o2K1RVMzRHVSNteUtLOjNzSCR5LUEyKk5qOEhFRg==", forHTTPHeaderField: "Authorization")
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",response)
}
if let data = data {
do {
let json = try JSONSerialization.jsonObject(with: data, options: [])
print(json)
} catch {
print(error)
}
}
}.resume()
}
Try this:
#IBAction func buton(_ sender: Any){
let params = ["acceptPrivacyNotice": true, "name" :"xxxxx xxxxx", "email": "xxxxx#mail.com", "password":"Qwerty2012", "passwordConfirm":"Qwerty2012","deviceID" : "", "isProvider" : false, "idTypeProvider": 1] as [String : Any]
let session = Foundation.URLSession.shared
let url = URL(string: "https://www.apps-sellcom-dev.com/Engie/api/account/register")
var request = URLRequest(url : url!)
request.httpMethod = "POST"
do {
let jsonData = try JSONSerialization.data(withJSONObject: params, options: .prettyPrinted)
request.addValue("M1o2K1RVMzRHVSNteUtLOjNzSCR5LUEyKk5qOEhFRg==", forHTTPHeaderField: "Authorization")
request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
request.httpBody = jsonData
session.dataTask(with: request, completionHandler: { data, response, error in
OperationQueue.main.addOperation {
guard error == nil && data != nil else {
print("error=\(String(describing: 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 = \(String(describing: response))")
}
let responseString = String(data: data!, encoding: String.Encoding.utf8)
print("responseString = \(responseString!)")
if let responsedata = responseString!.data(using: String.Encoding.utf8)! as? Data{
do {
let jsonResult:NSDictionary = try JSONSerialization.jsonObject(with: responsedata, options: []) as! NSDictionary
print("Get The Result \(jsonResult)")
if error != nil {
print("error=\(String(describing: error))")
}
if let str = jsonResult["success"] as? NSNull {
print("error=\(str)")
}
else {
let responseString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
print("Response string : \(String(describing: responseString))")
}
} catch let error as NSError {
print(error.localizedDescription)
}
}
}
}) .resume()
}catch {
}
}
I've tested your code and the reason you are not seeing a response is that the completion block doesn't do anything in case of failure.
When I ran your request, it came back with the following error
Error Domain=NSPOSIXErrorDomain Code=100 "Protocol error" UserInfo={NSErrorPeerAddressKey=<CFData 0x608000092200 [0x101840c70]>{length = 16, capacity = 16, bytes = 0x100201bb34bface50000000000000000}, _kCFStreamErrorCodeKey=100, _kCFStreamErrorDomainKey=1}
My best guess is that there is something wrong in the httpBody. Hope that helps.
I am facing some problem in a POST query; please help. It always sends me a 400 Bad request response. I have checked everything thoroughly but its just not working. Please help.
Code is -
struct RegisterService {
var authToken: String = ""
var baseURL = NSURL(string: "")
func getToken(name: String, email: String, password: String, cfmpassword: String, completion: (AuthToken? -> Void)) {
let request = NSMutableURLRequest(URL: baseURL!)
let session = NSURLSession.sharedSession()
request.HTTPMethod = "POST"
let params = ["accept":"on", "cfmpassword":"\(cfmpassword)",
"email":"\(email)", "name":"\(name)", "password":"\(password)"]
as Dictionary<String, AnyObject>
do {
request.HTTPBody = try NSJSONSerialization.dataWithJSONObject(params, options: [])
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
} catch {
print("Request Unsuccessful")
}
let task = session.dataTaskWithRequest(request, completionHandler: {data, response, error -> Void in
print(request)
print(data)
print(response)
if let httpResponse = response as? NSHTTPURLResponse {
switch httpResponse.statusCode {
case 200:
// 2. Create JSON object with data
do {
let jsonDictionary = try NSJSONSerialization.JSONObjectWithData(data!, options: []) as? [String: AnyObject]
let authToken = AuthToken(tokenDictionary: jsonDictionary!)
completion(authToken)
} catch {
print("Fetch failed: \((error as NSError).localizedDescription)")
}
default:
print("GET request not successful. HTTP status code: \(httpResponse.statusCode)")
NSOperationQueue.mainQueue().addOperationWithBlock {
completion(nil)
}
}
} else {
print("Error: Not a valid HTTP response")
NSOperationQueue.mainQueue().addOperationWithBlock {
completion(nil)
}
}
})
task.resume()
}
}
let params = ["accept":"on", "cfmpassword":"\(cfmpassword)", "email":"\(email)", "name":"\(name)", "password":"\(password)"] as Dictionary<String, AnyObject>
let boundary:String = "---------------------------14737809831466499882746641449"
let body:NSMutableData = NSMutableData()
if params != nil
{
for (key, value) in params!
{
body.appendString("--\(boundary)\r\n")
body.appendString("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n")
body.appendString("\(value)\r\n")
}
}
body.appendString("--\(boundary)--\r\n")
request.setValue("\(body.length)", forHTTPHeaderField:"Content-Length")
request.HTTPBody = body