Swift - NSJsonSerialization - "Unable to convert data to string around character" error - ios

I got below error when try to post an url with a dictionary as param;
NSCocoaErrorDomain Code=3840 "Unable to convert data to string around
character 34
And my code below;
func postOrder() {
let params = [
“date”: ”25.12.2015”,
“time” : “22:34”,
“order_no”: “23232322”,
"user_id" : “23232”
] as Dictionary<String, String>
let request = NSMutableURLRequest(URL: NSURL(string: "http://webservis.xxxxx.com/post_order.asp")!)
let session = NSURLSession.sharedSession()
request.HTTPMethod = "POST"
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
request.HTTPBody = try! NSJSONSerialization.dataWithJSONObject(params, options: [])
let task = session.dataTaskWithRequest(request) { data, response, error in
guard data != nil else {
print("no data found: \(error)")
return
}
let cfEnc = CFStringEncodings.ISOLatin5
let enc = CFStringConvertEncodingToNSStringEncoding(CFStringEncoding(cfEnc.rawValue))
let outputString = NSString(data: data!, encoding: enc)
do {
if let json = try NSJSONSerialization.JSONObjectWithData(data!, options: []) as? NSDictionary {
let success = json["success"] as? Int
print("Success: \(success)")
} else {
let cfEnc = CFStringEncodings.ISOLatin5
let enc = CFStringConvertEncodingToNSStringEncoding(CFStringEncoding(cfEnc.rawValue))
let jsonStr = NSString(data: data!, encoding: enc)
print("Error could not parse JSON: \(jsonStr)")
}
} catch let parseError {
print(parseError)
let cfEnc = CFStringEncodings.ISOLatin5
let enc = CFStringConvertEncodingToNSStringEncoding(CFStringEncoding(cfEnc.rawValue))
let jsonStr = NSString(data: data!, encoding: enc)
print("Error could not parse JSON: '\(jsonStr)'")
}
}
task.resume()
}
What is the problem on above code, can anybody help?

Check that the data you're parsing is actually valid JSON (and not just 'nearly' JSON). That error is known to occur when you have a different data format that can't be parsed as JSON.
Replace your params with the following and try again.
let params = [
"date": "25.12.2015",
"time" : "22:34",
"order_no": "23232322",
"user_id" : "23232"
] as Dictionary<String, String>
Furthermore, you may check the following thread iOS 5 JSON Parsing Results in Cocoa Error 3840

Related

JSON response format is incorrect(Swift)

I am new to Swift and I am getting response from mysql through PHP script in JSON format. But my JSON is in correct format :
["Result": <__NSArrayI 0x60000005bc60>(
<__NSArray0 0x608000000610>(
)
,
{
name = "abc" ;
address = "abc address"
},
{
name = "xyz" ;
address = "xyz address"
}
)
]
my code for serialisation is :
let url = URL(string: "my url")
var request = URLRequest(url: url!)
request.httpMethod = "POST"
let body = "Id=\(Id)"
request.httpBody = body.data(using: .utf8)
// request.addValue("application/json", forHTTPHeaderField: "Content-type")
URLSession.shared.dataTask(with: request) { data, response, error in
if error == nil {
DispatchQueue.main.async(execute: {
do {
if let json = try! JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? Dictionary<String,Any>{
print(json)
Where am I going wrong?
POSTMAN output
{
"Result": [
{
name = "abc" ;
address = "abc address"
},
{
name = "xyz" ;
address = "xyz address"
}
]
}
Try it once.
let json = try! JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [String:Any]
Swift 3.0
Try this code..
//declare parameter as a dictionary
let parameters = ["Id": Id"] as Dictionary<String, String>
//url
let url = URL(string: "http://test.com/api")!
//session object
let session = URLSession.shared
//URLRequest object using the url object
var request = URLRequest(url: url)
request.httpMethod = "POST"
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("application/json", forHTTPHeaderField: "Accept")
let task = session.dataTask(with: request as URLRequest, completionHandler: { data, response, error in
guard error == nil else {
return
}
guard let data = data else {
return
}
do {
//json object from data
if let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String: Any] {
print(json)
// handle json...
}
} catch let error {
print(error.localizedDescription)
}
})
task.resume()
Alamofire
Try this code using Alamofire..
let parameters = [
"name": "user1"]
let url = "https://myurl.com/api"
Alamofire.request(url, method:.post, parameters:parameters,encoding: JSONEncoding.default).responseJSON { response in
switch response.result {
case .success:
print(response)
case .failure(let error):
failure(0,"Error")
}
}
Make sure you get the response as json. Some times get string as response. If you get string then convert that json string to json object.
Check it is a valid json object
let valid = JSONSerialization.isValidJSONObject(jsonOBJ) // jsonOBJ is the response from server
print(valid) // if true then it is a valid json object

The data couldn’t be read because it isn’t in the correct format - HTTP network

code
let session = URLSession.shared
// prepare json data
let json: [String: Any] = ["email": "test_mobile#mysite.com"]
let jsonData = try? JSONSerialization.data(withJSONObject: json)
let proceedURL = NSURL(string:"https://mysitename.herokuapp.com/api/users/isUser")
//let proceedURL = NSURL(string:"https://google.com")
let request = NSMutableURLRequest(url: proceedURL! as URL)
//HTTP Headers
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/www.inception.v1", forHTTPHeaderField: "Accept")
request.addValue("Authorization", forHTTPHeaderField: "Basic aW5jZXB0aW9uQGZ1cmRvOmljM=")
request.httpMethod = "POST"
//request.httpBody = jsonData
// insert json data to the request
request.httpBody = jsonData
//create dataTask using the session object to send data to the server
let task = session.dataTask(with: request as URLRequest, completionHandler: { data, response, error in
guard error == nil else {
return
}
guard let data = data else {
return
}
// Print out response string
let responseString = NSString(data: data, encoding: String.Encoding.utf8.rawValue)
print("responseString = \(responseString!)")
do {
//create json object from data
if let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String: AnyObject] {
print(json)
// handle json...
}
} catch let error {
print("error : " + error.localizedDescription)
}
})
task.resume()
error :
The data couldn’t be read because it isn’t in the correct format.
I am beginner in iphone app development, help me on it and give better suggestion for make network connection (like in android i am using Volley library )
Actual Response is :
{
"status": 1,
"http_status_code": 200,
"data": {
"email": "test_mobile#mysite.com",
"phone": "8090909000"
}
}
i am using same on Android and test in postmen.
// Print out response string
let responseString = NSString(data: data, encoding: String.Encoding.utf8.rawValue)
for upper code response is nothing
Using Alamofire.
let json: [String: Any] = ["email": "test_mobile#mysite.com"]
Alamofire.request(.POST, "https://mysitename.herokuapp.com/api/users/isUser" , parameters: json, encoding: .JSON).responseJSON {
Response in
switch Response.result {
case .Success(let _data):
let JsonData = JSON(_data)
print("JsonData : \(JsonData)")
//handle json
case .Failure(let _error):
print(_error)
let AlertBox = UIAlertController(title: "Connection Failed", message: "No Connection", preferredStyle: .Alert)
let ActionBox = UIAlertAction(title: "Ok" , style: .Default, handler: { _ in})
AlertBox.addAction(ActionBox)
self.presentViewController(AlertBox, animated: true, completion: nil)
}
let json: [String: Any] = ["email": "test_mobile#mysite.com"]
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"
request.setValue("application/json; charset=utf-8", 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)
}
}
task.resume()

How to login by POST method or How to access data by POST method

I am trying to get data from API with multiple parameter and using Headers.
i try a lot but not success, problem is that i can do this using Alamofire. but i want to do it by NSURLSession.
func apiCalling(){
let myUrl = NSURL(string: "http://203.XXXXXXXXX.php");
let request = NSMutableURLRequest(URL:myUrl!);
request.HTTPMethod = "POST";// Compose a query string
request.addValue("KAISAPAISA", forHTTPHeaderField: "APIXXXXX")
let postString = "uname=demo&password=demo123";
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding);
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
data, response, error in
if error != nil
{
print("error=\(error)")
return
}
// You can print out response object
print("response = \(response)")
// Print out response body
let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding)
print("responseString = \(responseString)")
//Let's convert response sent from a server side script to a NSDictionary object:
do {
let myJSON = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableContainers) as? NSDictionary
if let parseJSON = myJSON {
// Now we can access value of First Name by its key
let firstNameValue = parseJSON["firstName"] as? String
print("firstNameValue: \(firstNameValue)")
}
} catch {
print(error)
}
}
task.resume()
}

Media type is unsupported error in json post method Swift

I'm new to swift and making a simple application that converts Celsius to Fahrenheit using this : JSON WebService
My code is on a button btn action:
#IBAction func btn(sender: AnyObject) {
let celnum = txtfirld.text
let myUrl = NSURL(string: "http://webservices.daehosting.com/services/TemperatureConversions.wso");
print("pass 1")
let request = NSMutableURLRequest(URL: myUrl!);
request.HTTPMethod = "POST";
print("pass 2")
let postString = "nCelsius=\(celnum)"
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding);
let task = NSURLSession.sharedSession().dataTaskWithRequest(request){
data, response, error in
print("pass 3")
if error != nil {
print("Error 1")
return
}
let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding)
print("responseString = \(responseString)")
do{
let json = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableLeaves) as? NSDictionary
if let parseJson = json{
let resultValue = parseJson["status"] as! String!
print("result:\(resultValue)")
}
} catch {print("Error 2")}
}
task.resume()
}
But it is giving me error like this on console:
pass 1
pass 2
pass 3
responseString = Optional(The server cannot service the request because the media type is unsupported.)
Error 2
Plaese help thank u :)
1 - You should set your request Content-Type :
request.setValue(" application/json; charset=utf-8", forHeader:"Content-Type")
2 - Your body is not in JSON format, use :
let params = ["nCelscius" : 1212]
request.HTTPBody = NSJSONSerialization.dataWithJSONObject(params, options: NSJSONWritingOptions())

Upload an Image to a RESTful API

hello I am successfully posting data into server but this time I want to upload an image to server. I am using this function to post the data without image
static func postToServer(url:String,params:Dictionary<String,NSObject>,image:String?, completionHandler: (NSDictionary?, String?) -> Void ) -> NSURLSessionTask {
let request = NSMutableURLRequest(URL: NSURL(string: url)!)
let session = NSURLSession.sharedSession()
request.HTTPMethod = "POST"
if(params["data"] != "get"){
do {
let data = try NSJSONSerialization.dataWithJSONObject(params, options: .PrettyPrinted)
let dataString = NSString(data: data, encoding: NSUTF8StringEncoding)!
print("dataString is \(dataString)")
request.HTTPBody = data//try NSJSONSerialization.dataWithJSONObject(params, options: .PrettyPrinted)
} catch {
//handle error. Probably return or mark function as throws
print("error is \(error)")
//return
}
}
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
let task = session.dataTaskWithRequest(request) {data, response, error -> Void in
// handle error
guard error == nil else { return }
//print("Response: \(response)")
let strData = NSString(data: data!, encoding: NSUTF8StringEncoding)
completionHandler(nil,"Body: \(strData!)")
//print("Body: \(strData!)")
let json: NSDictionary?
do {
json = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableLeaves) as? NSDictionary
} catch let dataError {
// Did the JSONObjectWithData constructor return an error? If so, log the error to the console
print(dataError)
let jsonStr = NSString(data: data!, encoding: NSUTF8StringEncoding)
print("Error could not parse JSON: '\(jsonStr)'")
completionHandler(nil,"Body: \(jsonStr!)")
// return or throw?
return
}
// The JSONObjectWithData constructor didn't return an error. But, we should still
// check and make sure that json has a value using optional binding.
if let parseJSON = json {
// Okay, the parsedJSON is here, let's get the value for 'success' out of it
completionHandler(parseJSON,nil)
//let success = parseJSON["success"] as? Int
//print("Succes: \(success)")
}
else {
// Woa, okay the json object was nil, something went worng. Maybe the server isn't running?
let jsonStr = NSString(data: data!, encoding: NSUTF8StringEncoding)
completionHandler(nil,"Body: \(jsonStr!)")
}
}
task.resume()
return task
}
Now as I have to send an image now also I think I have to do this
var imageData = UIImageJPEGRepresentation(image, 0.9)
var base64String = imageData.base64EncodedStringWithOptions(NSDataBase64EncodingOptions.fromRaw(0)!)
var params = ["image":[ "content_type": "image/jpeg", "filename":"test.jpg", "file_data": base64String]]
now the problem is how can I add these params in the above params variable. I mean right now the format of my params is like this
{
"email" : "hello",
"password" : "hello"
}
Could you not just add them to the params you already have, like this?
var params = ["email":"hello", "password":"hello"]
params["image"] = ["content_type": "image/jpeg", "filename":"test.jpg", "file_data": base64String]

Resources