JSON response format is incorrect(Swift) - ios

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

Related

Issue in parsing Json Response in iOS application, getting "=" at the place of ":" in Dictionary

I am working on an iOS application and using swift in it. I am calling an Rest api and response is JSON.
Here is my code:
{
let request = NSMutableURLRequest(url: NSURL(string: path)! as URL)
// Set the method to POST
request.httpMethod = "POST"
do {
// Set the POST body for the request
let jsonBody = try JSONSerialization.data(withJSONObject: body, options: .prettyPrinted)
request.httpBody = jsonBody
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
// request.addValue("Cookie", forHTTPHeaderField: session_Id)
let session = URLSession.shared
let task = session.dataTask(with: request as URLRequest, completionHandler: {data, response, error -> Void in
if let jsonData = data {
print("\(data?.debugDescription)")
do {
print("JSON Response String: \(String.init(data: data!, encoding: .utf8))")
let dict:[String:Any] = (try JSONSerialization.jsonObject(with: jsonData, options: []) as? [String:Any])!
print("JSON Response Dictionary: \(dict)")
onCompletion(dict, nil)
} catch {
// report ERROR
print("caught: \(error)")
onCompletion(nil, error as! NSError)
}
} else {
print(error)
onCompletion(nil, error as! NSError)
}
})
task.resume()
} catch {
// Create your personal error
onCompletion(nil, nil)
}
}
And This is the response of api:
======== - Fetch CC list api request - =============
["userID": "898465844"]
======== - Fetch CC list api request - =============
JSON Response String: "{\"status\":\"success\",\"card_list\":[{\"cardType\":\"Visa\",\"cardholderName\":null,\"expirationMonth\":\"01\",\"expirationYear\":\"2020\",\"cardImage\":\"https://assets.braintreegateway.com/payment_method_logo/visa.png?environment=sandbox\",\"cardNumber\":\"411111******1111\",\"token\":\"348nws\"}]}"
JSON Response Dictionary: ["status": success, "card_list": <__NSSingleObjectArrayI 0x1c060f350>(
{
cardImage = "https://assets.braintreegateway.com/payment_method_logo/visa.png?environment=sandbox";
cardNumber = "411111******1111";
cardType = Visa;
cardholderName = "<null>";
expirationMonth = 01;
expirationYear = 2020;
token = 348nws;
}
)
]
After parsing I am getting "=" at the place of ":" in "card_list" array of dictionary.
So I am not able to figure out why I am getting "=" at the place of ":".
The format of your response is not look like JSON. Its property list or (XML) try to use - PropertyListSerialization.propertyList(from:...) or some XML parsers

How to resolve issue? I given description in body

// Hi, i got response from url but getting error as below in title, please fix the issue.
Error Domain=NSCocoaErrorDomain Code=3840 "Invalid value around character 0." UserInfo={NSDebugDescription=Invalid value around character 0
let Url = String(format: "http://www.fgndbdsn.in/index.php?route=api/mywebservices/addition")
guard let serviceUrl = URL(string: Url) else { return }
let parameterDictionary = ["first" : "25", "second" : "25"]
var request = URLRequest(url: serviceUrl)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
guard let httpBody = try? JSONSerialization.data(withJSONObject: parameterDictionary, 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 {
print(data)
do {
let json = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as! [[String:Any]]
print(json)
}catch {
print(error)
}
}
}.resume()
The response from the server must be valid JSON with a top level container which is an array or dictionary.

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()

Why format is strange when JSON is parsed in Swift3?

I have a struggle in parsing JSON data using Oxford Dictionary API. I can retrieve JSON data and at this point, there is no problem. But the format is a bit strange. In the example of JSON data by OXford Document, it looks like;
"results": [
{
"id": "string",
"language": "string",
"lexicalEntries": [
{
"entries": [
{..........
Unlike the example above, the array in my JSON is not surrouned by [], but ()
Why is this happening??
Updated
I used Alamofire to produce it. The code is;
func getJSONData() {
let appId = ""
let appKey = ""
let language = "en"
let word = "play"
let word_id = word.lowercased()
let url = URL(string: "https://od-api.oxforddictionaries.com/api/v1/entries/\(language)/\(word_id)")!
var request = URLRequest(url: url)
request.addValue("application/json", forHTTPHeaderField: "Accept")
request.addValue(appId, forHTTPHeaderField: "app_id")
request.addValue(appKey, forHTTPHeaderField: "app_key")
Alamofire.request(request).responseJSON { response in
print("Request \(response.request)") // original URL request
print("Response \(response.response)") // HTTP URL response
print("Data \(response.data)") // server data
print("Result \(response.result)") // result of response serialization
if let JSON = response.result.value {
print("JSON: \(JSON)")
}
}
}
I followed all code in Oxford Dictionary Document, but the printed out JSON was far from the JSON in the document. So I tried to use Alamofire in the hope for it to work correctly, but the result was the same. https://developer.oxforddictionaries.com/documentation
Update2
Okay, I understood why this was an error. To people who might have the same problem, I post the answer for the problem I had.
enum JSONError: String, Error {
case NoData = "ERROR: no data"
case ConversionFailed = "ERROR: conversion from JSON failed"
}
func jsonParser() {
let appId = ""
let appKey = ""
let language = "en"
let word = "Ace"
let word_id = word.lowercased() //word id is case sensitive and lowercase is required
let url = URL(string: "https://od-api.oxforddictionaries.com:443/api/v1/entries/\(language)/\(word_id)")!
var request = URLRequest(url: url)
request.addValue("application/json", forHTTPHeaderField: "Accept")
request.addValue(appId, forHTTPHeaderField: "app_id")
request.addValue(appKey, forHTTPHeaderField: "app_key")
URLSession.shared.dataTask(with: request) { (data, response, error) in
do {
guard let data = data else {
throw JSONError.NoData
}
guard let json = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as? NSDictionary else {
throw JSONError.ConversionFailed
}
if let stringJSON = String(data: data, encoding: String.Encoding.utf8) {
print(stringJSON)
}
print(json)
} catch let error as JSONError {
print(error.rawValue)
} catch let error as NSError {
print(error.debugDescription)
}
}.resume()
}
Strange printed JSON format This post helped me. This bugged me for a while. Thank you very much #EricAya

POST w/ JSON Body - Swift3 - fragments?

I'm simply trying to send a JSON string via a Swift3 httprequest.
Tried using a Dictionary, and an escaped string ...
func getToken(successHandler: #escaping (Any) -> Void, errorHandler: #escaping (Any) -> Void) {
var request = URLRequest(url: URL(string: "http://my-api.domain.com/getToken")!)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
do
{
// try with Dictionary
let bodyJson: [String: String] = [
"username": "theusername"
]
let bodyJsonData = try JSONSerialization.data(withJSONObject: bodyJson, options: [])
// try with escaped String
let jsonString = "{" +
"\"username\": \"theusername\"," +
"}"
let jsonStringData = jsonString.data(using: String.Encoding.utf8)
//request.httpBody = bodyJsonData
request.httpBody = jsonStringData
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard error == nil else {
print(error)
errorHandler(error)
return
}
guard let data = data else {
print("Data is empty")
errorHandler("Data is empty")
return
}
var json: Any? = nil
do
{
json = try JSONSerialization.jsonObject(with: data, options: [])
DispatchQueue.main.asyncAfter(deadline: .now()) {
successHandler(json)
}
}
catch let error as NSError {
errorHandler(error)
}
}
task.resume()
}
catch
{
errorHandler(error)
}
}
I keep getting:
Handle Error: Error Domain=NSCocoaErrorDomain Code=3840 "JSON text did
not start with array or object and option to allow fragments not set."
UserInfo={NSDebugDescription=JSON text did not start with array or
object and option to allow fragments not set.}
I can't find how to try allowing fragments, all of the examples/tutorials are for Swift2.x :/
Unsure what to do!
// prepare json data
let mapDict = [ "1":"First", "2":"Second"]
let json = [ "title":"ABC" , "dict": mapDict ] as [String : Any]
do {
let jsonData = try JSONSerialization.data(withJSONObject: json, options: .prettyPrinted)
// create post request
let endpoint: String = "https://yourAPI"
let session = URLSession.shared
let url = NSURL(string: endpoint)!
let request = NSMutableURLRequest(url: url as URL)
request.httpMethod = "POST"
// insert json data to the request
request.httpBody = jsonData
let task = session.dataTask(with: request as URLRequest){ data,response,error in
if error != nil{
print(error?.localizedDescription)
return
}
}
task.resume()
} catch {
print("bad things happened")
}

Resources