Swift iOS HTTP request post json - ios

I want to make a HTTP request to a server but I have troubles parsing my data to JSON.
This is my code:
let dic = ["interest":["category":"Viajes","value":"Mexico"],"metadata":["version":"0.1","count":1]]
do{
let jsonData = try NSJSONSerialization.dataWithJSONObject(dic, options: NSJSONWritingOptions())
let url:NSURL = NSURL(string: "http://ip/interests")!
let session = NSURLSession.sharedSession()
let request = NSMutableURLRequest(URL: url)
request.HTTPMethod = "POST"
request.cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringCacheData
//let paramString = ""
//request.HTTPBody = paramString.dataUsingEncoding(NSUTF8StringEncoding)
request.HTTPBody = jsonData
let dataString = NSString(data: jsonData, encoding: NSUTF8StringEncoding)
print(dataString)
let task = session.dataTaskWithRequest(request) {
(
let data, let response, let error) in
guard let _:NSData = data, let _:NSURLResponse = response where error == nil else {
print(error)
return
}
print(response?.description)
}
task.resume()
}catch let error as NSError {
print(error)
return
}
The server catch :
{ '{"interest":{"category":"Viajes","value":"Mexico"},"metadata":{"count":1,"version":"0.1"}}': '' }
What I want:
{"interest":{"category":"Viajes","value":"Mexico"},"metadata":{"count":1,"version":"0.1"}}
Anybody knows how to fix it?

Related

Siri Shortcut Intent API call says URL is nil, but its not

Here is the code that I am dealing with:
let url = "https://www.host.com/url/\(intent.cardInfo!)"
print(url)
let url2 = URL(string: url)! // this is nil??
let request = NSMutableURLRequest(url: url2)
Below is an image showing that this value is not nil (you can see that in the console). I get the value after the Siri intent. This is inside of the IntentHandler. All of the code is below.
class SoldForAppIntentHandler : NSObject, SoldForAppIntentHandling {
func handle(intent: SoldForAppIntent, completion: #escaping (SoldForAppIntentResponse) -> Void) {
print(intent.sport!)
print(intent.cardInfo!)
print(intent.cardNumber!)
let url = "https://www.host.com/url/\(intent.cardInfo!)"
print(url)
let url2 = URL(string: url)!
let request = NSMutableURLRequest(url: url2)
request.httpMethod = "GET"
let postString = ""
request.httpBody = postString.data(using: String.Encoding.utf8)
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
let task = URLSession.shared.dataTask(with: request as URLRequest) {
data, response, error in
if error != nil {
print("error=\(error)")
return
}
let responseString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
do {
let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSDictionary
//print(json!)
let response = json!["value"] as! String
} catch {
print(" error adding tap search to db:\(error)")
}
print()
}
task.resume()
completion(SoldForAppIntentResponse.success(response: "\n\nSold For will look up \(intent.sport!) \(intent.cardInfo!) \(intent.cardNumber!)"))
}
Problem is actually url2 itself, because the string https://www.host.com/url/1986 fleer 57 Michael Jordan PSA 10 cannot be properly converted into URL object.
You can try something like this:
if let url = "https://www.host.com/url/\(intent.cardInfo!)".addingPercentEncoding(withAllowedCharacters: .urlHostAllowed) {
let url2 = URL(string: url)!
}

Sending Http Post request returns 500 status code in IoS

I am trying to send Receipt data of NSData type(converted to string) and several other parameters of type as String in Http Post request.
func receiptValidation(productId:String)
{
let SUBSCRIPTION_SECRET = My_SecretKey
let defaults = UserDefaults.standard
let receiptPath = Bundle.main.appStoreReceiptURL?.path
if FileManager.default.fileExists(atPath: receiptPath!){
var receiptData:NSData?
do{
receiptData = try NSData(contentsOf: Bundle.main.appStoreReceiptURL!, options: NSData.ReadingOptions.alwaysMapped)
}
catch{
print("ERROR: " + error.localizedDescription)
}
let receiptString = receiptData?.base64EncodedString(options: NSData.Base64EncodingOptions(rawValue: 0))
// let base64encodedReceipt = receiptData?.base64EncodedString(options: NSData.Base64EncodingOptions.endLineWithCarriageReturn)
let requestDictionary = ["receipt-data":receiptString!,"password":SUBSCRIPTION_SECRET]
guard JSONSerialization.isValidJSONObject(requestDictionary) else { print("requestDictionary is not valid JSON"); return }
do {
let requestData = try JSONSerialization.data(withJSONObject: requestDictionary)
let requestDataString = NSString(data: requestData, encoding: String.Encoding.utf8.rawValue)
//https://<apiProxyServer>:<apiProxyServerPort>/api/validate-receipt-data
let URLForApplication:String = String(format:"%#/api/validate-receipt-data",opcodeDetails["apiProxyBaseUrl"]!) // this works but as noted above it's best to use your own trusted server
let url:URL! = URL.init(string: URLForApplication)
var request = URLRequest.init(url: url)
request.httpMethod = "POST"
let configure = URLSessionConfiguration.background(withIdentifier: Bundle.main.bundleIdentifier!)
var postString:[String:Any]=[
"receiptData": requestDataString
"deviceType":"IOS",
"subscriberId":encodeString(normalString: defaults.array(forKey: "userDetails")?.first as! String),
"password":encodeString(normalString: defaults.array(forKey: "userDetails")?.last as! String),
"productId":encodeString(normalString: productId),
"code":opcodeDetails["opCode"]!
]
do {
let receiptData = try JSONSerialization.data(withJSONObject: postString)
request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
request.httpBody = receiptData
} catch let error {
print(error.localizedDescription)
}
let session = URLSession(configuration:configure,
delegate:applicationDelegate.application,
delegateQueue:OperationQueue.main)
session1 = session
let connection = session1?.dataTask(with: request)
connection?.resume()
} catch let error as NSError {
print("json serialization failed with error: \(error)")
}
}
}
Where encodeString() is a defined method
func encodeString(normalString:String) -> String {
let allowedCharacters = CharacterSet.letters
let encodedString:String!=normalString.addingPercentEncoding(withAllowedCharacters: allowedCharacters)
return encodedString
}
There were no problem on server side.But I could not get success response instead What I am getting is {"status":"failure","statusCode":500,"message":"Resource url not found!"}.What mistake am i doing with this code?.Anyone please help me.Thanks in advance.
Try appending '/' at the end of URL.
Eg:
google.com/api/post and google.com/api/post/ are different and trailing slash sometimes gives 500 error, in case of Django-Backend it does.

Swift - JSON data wont display in UITableview

I am trying to retrieve data from a server. I can display my data in the console.
I'm trying to display it in a UITableview but nothing happens.
I tried to create a local JSON file and I am able to display it, but when coming from the server it wont work.
let newUrl = URL(string: urlGetNotifications)
let configuration = URLSessionConfiguration.default
var session = URLSession.shared
var request = URLRequest(url: newUrl!)
session = URLSession(configuration: configuration)
request.httpMethod = "GET"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
request.setValue(authkeyFCM, forHTTPHeaderField: "auth-key")
request.setValue(tokenFCM.string(forKey: "tokenFCM"), forHTTPHeaderField: "token")
let task = session.dataTask(with: request as URLRequest, completionHandler: { data, response, error in
DispatchQueue.main.async {
guard let j = newUrl
else{
print("data not found")
return
}
guard let d = try? Data(contentsOf: j)
else { print("failed")
return
}
guard let rootJSON = try? JSONSerialization.jsonObject(with: d, options: [])
else{ print("failedh")
return
}
if let data = data, let dataString = String(data: data, encoding: .utf8) {
if let JSON = rootJSON as? [String: Any] {
print("data: \(dataString)")
guard let jsonArray = JSON["data"] as? [[String: Any]] else {
return
}
print(jsonArray)
let name = jsonArray[0]["type"] as? String
print(name ?? "NA")
print(jsonArray.last!["created_at"] as? String as Any)
self.notificationList = jsonArray.compactMap{return NotificationData($0)}
self.tableView.reloadData()
}
}
}
})
task.resume()
create a variable for the URL and create struct contain the all param
in the main add variable of type the struck then start fetch the data
var users: [User]() = []
func fetchUsers(using url: String){
let url = URL(string: url)!
let _ = URLSession.shared.dataTask(with: url){ (data,response,error)
in
guard let data = data else {return}
do{
let userFetch = try JSONDecoder().decode([Post].self, from: data) // decode * ( Codable )
self.users = userFetch
self.load(with: userFetch)
self.userCollection = userFetch
DispatchQueue.main.async {
self.collectionView.reloadData()
}
} catch{
print("error loading data cause: \(error)")
}
}.resume()
}
I figured it out
This one works
let newUrl = URL(string: urlGetNotifications)
let configuration = URLSessionConfiguration.default
var session = URLSession.shared
var request = URLRequest(url: newUrl!)
session = URLSession(configuration: configuration)
request.httpMethod = "GET"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
request.setValue(authkeyFCM, forHTTPHeaderField: "auth-key")
request.setValue(tokenFCM.string(forKey: "tokenFCM"), forHTTPHeaderField: "token")
let task = session.dataTask(with: request as URLRequest, completionHandler: { data, response, error in
DispatchQueue.main.async {
do {
let json = try JSONSerialization.jsonObject(with: data!, options: [])
//self.showSpinner(onView: self.view)
print("The Response is : ",json)
if let data = data, let dataString = String(data: data, encoding: .utf8) {
if let JSON = json as? [String: Any] {
print("dumaan ba dito")
print("data: \(dataString)")
guard let jsonArray = JSON["data"] as? [[String: Any]] else {
return
}
print(jsonArray)
let name = jsonArray[0]["type"] as? String
print(name ?? "NA")
print(jsonArray.last!["created_at"] as? String as Any)
self.notificationList = jsonArray.compactMap{return NotificationData($0)}
self.tableView.reloadData()
}
}
} catch {
print("JSON error: \(error.localizedDescription)")
}
} // end
})
task.resume()

How to make rest api call with HTTP PUT method in swift

I have tried the below REST Api with PUT method.
Here is my code,
let url = NSURL(string: "http://sampleurl")
let request = NSMutableURLRequest(URL: url!)
request.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.HTTPMethod = "PUT"
let session = NSURLSession(configuration:NSURLSessionConfiguration.defaultSessionConfiguration(), delegate: nil, delegateQueue: nil)
let params:[String: AnyObject] = ["deviceId" : "device_1","mobileDeviceId" : "abcd","deviceType":"ios"]
request.HTTPBody = NSJSONSerialization.dataWithJSONObject(params, options: NSJSONWritingOptions(), error: nil)
let dataTask = session.dataTaskWithRequest(request) { (data, response, error) -> Void in
if error != nil {
//handle error
print("Parsed error: '\(error)'")
}
else {
let jsonStr = NSString(data: data!, encoding: NSUTF8StringEncoding)
print("Parsed JSON: '\(jsonStr)'")
}
}
dataTask.resume()
It is not working. Please help me to find out where it is wrong.
This is a working code, I send your dictionary as a JSON formatted string to the server, and in the server, I parse the request and build another JSON object that contains the same values as the request, and send them back to the app. In the app, I parse the response and print the results:
let session = NSURLSession.sharedSession()
let url = "http://localhost:8080/yourServerGoesHere/putMethodTest"
let request = NSMutableURLRequest(URL: NSURL(string: url)!)
request.HTTPMethod = "PUT"
let params:[String: AnyObject] = ["deviceId" : "device_1","mobileDeviceId" : "abcd","deviceType":"ios"]
do{
request.HTTPBody = try NSJSONSerialization.dataWithJSONObject(params, options: NSJSONWritingOptions())
let task = session.dataTaskWithRequest(request, completionHandler: {(data, response, error) in
if let response = response {
let nsHTTPResponse = response as! NSHTTPURLResponse
let statusCode = nsHTTPResponse.statusCode
print ("status code = \(statusCode)")
}
if let error = error {
print ("\(error)")
}
if let data = data {
do{
let jsonData = try NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions())
let deviceId = jsonData["deviceId"] as! String
let mobileDeviceId = jsonData["mobileDeviceId"] as! String
let deviceType = jsonData["deviceType"] as! String
print (" deviceId= \(deviceId), mobileDeviceId= \(mobileDeviceId), deviceType= \(deviceType)")
}catch _ {
print ("the response is not well JSON formatted")
}
}
})
task.resume()
}catch _ {
print ("Oops something happened buddy")
}
If you want to try, this is the Java web service code:
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
#Path("/putMethodTest")
#PUT
#Consumes(MediaType.TEXT_PLAIN)
public Response putMethodTest(String requestString) {
JSONObject requestJSON = new JSONObject(requestString);
String deviceId = requestJSON.getString("deviceId");
String mobileDeviceId = requestJSON.getString("mobileDeviceId");
String deviceType = requestJSON.getString("deviceType");
JSONObject response = new JSONObject();
response.put("deviceId", deviceId);
response.put("mobileDeviceId", mobileDeviceId);
response.put("deviceType", deviceType);
return Response.ok().entity(response.toString()).build();
}
Define the put function like this :
//
// Put request
//
static func put(path: String, accessToken: Bool, data: Dictionary<String, AnyObject>, finish: (accessTokenX:String, data: JSON) -> ()) {
apiRequest("PUT", path: path, accessToken: accessToken, contentType: nil, data: data) { (accessTokenX:String, data: AnyObject) in
dispatch_async(dispatch_get_main_queue(), {
finish(accessTokenX:accessTokenX, data: JSON(data))
})
}
}
An example of use :
//
// Update informations of the profile
//
static func accountUpdate(profile: [String: AnyObject], finish: (accessTokenX:String, data: JSON) -> ()) {
let dataProfile = ["profile": profile]
API.put("/users/profile", accessToken: true, data: dataProfile) { accessTokenX, data in finish(accessTokenX:accessTokenX, data: data)
}
}
Try this!!!
http://jamesonquave.com/blog/making-a-post-request-in-swift/
func data_request()
{
let url:NSURL = NSURL(string: url_to_request)!
let session = NSURLSession.sharedSession()
let request = NSMutableURLRequest(URL: url)
request.HTTPMethod = "POST"
request.cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringCacheData
let paramString = "data=Hello"
request.HTTPBody = paramString.dataUsingEncoding(NSUTF8StringEncoding)
let task = session.dataTaskWithRequest(request) {
(
let data, let response, let error) in
guard let _:NSData = data, let _:NSURLResponse = response where error == nil else {
print("error")
return
}
let dataString = NSString(data: data!, encoding: NSUTF8StringEncoding)
print(dataString)
}
task.resume()
}

session.dataTaskWithURL is not executing in proper sequence

I am calling Web service.
In that method session.dataTaskWithURL is calling after some time.I think it is not giving in proper thread?
my code below
——--------------
func callService(usr: String, pwdCode: String) ->Bool
{
var resultPage=false
let url = NSURL(string: "demourl")
var xmlParse:NSString = ""
var data : NSData!
println("Before request *****************")
let config = NSURLSessionConfiguration.defaultSessionConfiguration()
let session = NSURLSession(configuration: config)
session.dataTaskWithURL(url!,
completionHandler: {(data, response, error) in
let request = NSMutableURLRequest(URL: url!)
request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
request.HTTPMethod = "POST"
let dictionary = ["email": usr, "userPwd": pwdCode] as NSDictionary
var error: NSError?
if let body = NSJSONSerialization.dataWithJSONObject(dictionary, options: nil, error: &error) {
request.HTTPBody = body
}
else
{
println("JSON error: \(error)")
}
let xmlParse=NSString(data: data, encoding: NSUTF8StringEncoding)!
if data == nil {
println("dataTaskWithRequest error: \(error)")
return
}
let parser = NSXMLParser(data: data)
parser.delegate = self
resultPage=parser.parse()
println("******** boolVal \(resultPage)")
}).resume()
println("After request *****************")
println("resultPage Final \(resultPage)")
return resultPage;
}
Can you please help me if we can execute my method "session.dataTaskWithURL(url!,
completionHandler: {(data, response, error) in " in a proper sequence???
Thanks in advance.
var resultPage=false
let url = NSURL(string: "URL")
var xmlParse:NSString = ""
var data : NSData!
let request = NSMutableURLRequest(URL: url!)
request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
request.HTTPMethod = "POST"
let dictionary = ["email": base64String, "userPwd": base64StringPwd] as NSDictionary
var error: NSError?
if let body = NSJSONSerialization.dataWithJSONObject(dictionary, options: nil, error: &error) {
request.HTTPBody = body
} else {
println("JSON error: \(error)")
}
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
(data, response, error) in
println(NSString(data: data, encoding: NSUTF8StringEncoding))
let xmlParse=NSString(data: data, encoding: NSUTF8StringEncoding)!
if data == nil {
println("dataTaskWithRequest error: \(error)")
return
}
let parser = NSXMLParser(data: data)
println("parser \(parser)")
parser.delegate = self
resultPage=parser.parse()
if self.success==false
{
println("success \(self.success)")
self.lblMessage.hidden=false
}
}
task.resume()

Resources