NSJSONSerialization no returns error - ios

There code:
var err: NSError
var jsonDict = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &err) as Array<NSDictionary>
If data has JSON it's works perfect. But if there something other (not JSON Array) it's just has fatal error and iOS simulator close with EXC_BAD_INSTRUCTION.
So there no call err. How I can check data before? Or catch the error.

(Sorry, am in a hurry, no description yet.)
var err: NSError?
var jsonDict: AnyObject!
var data: AnyObject = "{ }".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)
if let d = data as? NSData {
jsonDict = NSJSONSerialization.JSONObjectWithData(d, options: NSJSONReadingOptions.MutableContainers, error: &err)
if let dict = jsonDict as? NSDictionary {
// Do something with `dict`
println(dict)
}
}

This probably happens because JSONObjectWithData is declared to return id, but in reality it returns NSDictionary*, NSArray* or nil - in Swift, assigning nil to a variable of type id crashes by design. You need to give jsonDict a type, probably an optional NSMutableDictionary* or NSMutableArray*.

Related

Check for http response format

I am making http call and receiving JSON response
var jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &err) as! NSDictionary
But when not receiving actual json this line fail with error cannot cast value of NSArray to NSDictionary
I understand why this happen my question is how to properly check what format is the response
I do like this in my api's:
typealias JSONType = (dictionary: [String:AnyObject]?, array: [AnyObject]?)
var error:NSError?
var json:AnyObject? = NSJSONSerialization.JSONObjectWithData(data, options: nil, error: &error)
if let dict = json as? [String:AnyObject] {
return (dict, nil)
}
else if let arr = json as? [AnyObject] {
return (nil, arr)
}
So when I return that JSONType I can change to use it as a dictionary or array by just:
json.array

JSON String to NSDictionary with Swift

I am trying to create a dictionary from data that is held in a server, I receive the data but I cannot convert the data to an NSDictionary, I believe it is held in an NSData Object
let JSONDictionary: Dictionary = NSJSONSerialization.JSONObjectWithData(JSONData!, options: nil, error: &error) as NSDictionary
This line of code is the one giving me the problem, it throws a BAD_EXEC_INSTRUCTION.
MY Question: How can I turn a JSON into an NSDictionary?
Your code does not do any error handling. But it can (and if this data comes from a web service, will) fail in multiple ways.
You have to make sure that your data object actually exists
You have to make sure that the data object can be converted to JSON
You have to make sure that the JSON actually contains a Dictionary
You should use Swifts conditional cast and it's optional binding capabilities.
The optional binding if let JSONData = JSONData checks that JSONData is not nil. The force unwrap (JSONData!) you use might crash if no data could be received.
The optional binding if let json = NSJSONSerialization.JSONObjectWithData checks if the data could be converted to a JSON object. The conditional cast as? NSDictionary checks if the JSON object is actually a dictionary. You currently don't use these checks, you cast the objects as NSDictionary. Which will crash, if the object is not valid json, or if its not a dictionary.
I would recommend something like this:
var error: NSError?
if let JSONData = JSONData { // Check 1
if let json: AnyObject = NSJSONSerialization.JSONObjectWithData(JSONData, options: nil, error: &error) { // Check 2
if let jsonDictionary = json as? NSDictionary { // Check 3
println("Dictionary received")
}
else {
if let jsonString = NSString(data: JSONData, encoding: NSUTF8StringEncoding) {
println("JSON String: \n\n \(jsonString)")
}
fatalError("JSON does not contain a dictionary \(json)")
}
}
else {
fatalError("Can't parse JSON \(error)")
}
}
else {
fatalError("JSONData is nil")
}
You could merge check 2 and 3 into one line and check if NSJSONSerialization can create a NSDictionary directly:
var error: NSError?
if let JSONData = JSONData { // Check 1.
if let JSONDictionary = NSJSONSerialization.JSONObjectWithData(JSONData, options: nil, error: &error) as? NSDictionary { // Check 2. and 3.
println("Dictionary received")
}
else {
if let jsonString = NSString(data: JSONData, encoding: NSUTF8StringEncoding) {
println("JSON: \n\n \(jsonString)")
}
fatalError("Can't parse JSON \(error)")
}
}
else {
fatalError("JSONData is nil")
}
Make sure to replace fatalError with appropriate error handling in your production code
Update for Swift 2.
Now you must use it inside a try catch block.
do {
let responseObject = try NSJSONSerialization.JSONObjectWithData(data, options: []) as! [String:AnyObject]
} catch let error as NSError {
print("error: \(error.localizedDescription)")
}
Here jsonResult will give you the response in NSDictionary:
let url = NSURL(string: path)
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithURL(url!, completionHandler: {data, response, error -> Void in
println("Task completed")
if(error != nil) {
// If there is an error in the web request, print it to the console
println(error.localizedDescription)
}
var err: NSError?
var jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &err) as NSDictionary
if(err != nil) {
// If there is an error parsing JSON, print it to the console
println("JSON Error \(err!.localizedDescription)")
}
})
task.resume()

Access data from NSDictionary

I'm trying to get data from an NSDictionary in Swift but I'm not able to do this.
Here is the code
let urlPath = "http://ws-report.goocity.it/Stats/json/GetReport"
let url: NSURL = NSURL(string: urlPath)!
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithURL(url, completionHandler: {data, response, error -> Void in
var result: NSDictionary
if error != nil {
// If there is an error in the web request, print it to the console
println(error.localizedDescription)
}
var err: NSError?
var jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &err) as NSDictionary
if err != nil {
// If there is an error parsing JSON, print it to the console
println("JSON Error \(err!.localizedDescription)")
}
else{
//var arr : NSArray = jsonResult.valueForKey("Stats") as NSArray
//var cash: String? = jsonResult.valueForKey("Cash") as? NSString
let stats = jsonResult["Stats"]! as [[String : AnyObject]]
}
})
task.resume()
You can see the JSON clicking on the urlPath.
I still receive the following error on the let stats = ...
Thread 5: EXC_BAD_ACCESS (code=EXC_I386_GPFLT)
I've just checked out few other posts here on stackoverflow and anywhere, but no answer is good for my issue.
I need to get all JSON field values in many variables (like cash, lastUpdate, totalPartners, etc).
Your json is not an array of Dictionaries, it is just a Dictionary.
Change [[String: AnyObject]] to [String: AnyObject] and it will work.

JSONSerialization and EXC_BAD_ACCESS

I fetch some information from a MYSQL database with the help of a php service. At the end i push it through echo json_encode($resultArray) to my app. Now I have a problem with JSONSerialization and here is my code.
If ( urlData != nil ) {
let res = response as NSHTTPURLResponse!;
NSLog("Response code: %ld", res.statusCode);
if (res.statusCode >= 200 && res.statusCode < 300)
{
var responseData:NSString = NSString(data:urlData!, encoding:NSUTF8StringEncoding)!
NSLog("Response ==> %#", responseData);
var error: NSError?
let jsonData2:NSDictionary = NSJSONSerialization.JSONObjectWithData(urlData!, options:NSJSONReadingOptions.MutableContainers , error: &error) as NSDictionary
let success:NSInteger = jsonData2.valueForKey("IdUser") as NSInteger
...
With this code i get an error message EXC_BAD_ACCESS in the line of NSJSONSerialization. Does anybody know why?
The responseDate have this example value:
[{"IdUser":"2","preName":"Max","lastName":"Muster"}]
Thanks in advance.
Your JSON response is not a NSDictionary. It is an array. Now this array has one item, which is, itself, a dictionary. But you have to parse the array first:
let array = NSJSONSerialization.JSONObjectWithData(urlData!, options:nil, error: &error) as NSArray
If you want to get the dictionary, you grab the first item from the array:
let dictionary = array[0] as NSDictionary
And if you want the field value from IdUser, you grab that string value and then call integerValue:
let idUser = dictionary["IdUser"]?.integerValue
By the way, if it's at all possible that the response may deviate in its format, you may want to be careful with your parsing of the response, employing optional binding to gracefully handle the absence of the data in the format you expected, e.g.:
var error: NSError?
if let array = NSJSONSerialization.JSONObjectWithData(urlData!, options:nil, error: &error) as? [[String: AnyObject]] {
if let dictionary = array.first {
if let idUser = dictionary["IdUser"]?.integerValue {
// `IdUser` definitely found; now check the value here
}
}
}
an easy way to parse json in swift use SwiftyJSON but if you do not want it, you can do so
if let jsonData2 = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions(0), error: nil) as? AnyObject {
}
but I strongly recommend to use SwiftyJSON

Unable to get the value of JSON - Swift

I tried to get the value of "seed" from json response. But i am getting nil.
Json Response:
{
"response": {
"params": {
"rows": "20",
"defType": "abc",
"seed": "381786611"
}
}
}
Swift Parsing:
if let responseHeader:AnyObject = object?["response"] as? NSDictionary {
if let t = (responseHeader["params"] as? NSDictionary){
let t1 = t["seed"] as? String
println("result is \(t1)") // This returns nil
}
}
Json Parsing
func processJsonToDictionary(object:AnyObject?) -> AnyObject?{
if object != nil {
if let data: AnyObject = object {
var parseError: NSError?
var jsonResult = NSJSONSerialization.JSONObjectWithData(object as NSData!, options: NSJSONReadingOptions.MutableContainers, error: &parseError) as? NSDictionary
if(parseError != nil){
return parseError
}
else{
return jsonResult
}
}
}
return nil
}
I am not able to get the value of t1. it always returns nil.
How can i get the value.
Also, I put a breakpoint and tried to print the value of t1. But the Xcode Keeps crashing. Why?
I think the major problem here is only accessing a JSON object in swift.
var error: NSError?
let jsonDict = NSJSONSerialization.JSONObjectWithData(jsonData, options: nil, error: &error) as NSDictionary
let resp = jsonDict["response"] as? NSDictionary
let params = resp?["params"]?["seed"]
let seed = params!! as NSString
This is just to show you how a JSON object is accessed in swift. You can ofcourse change it according to your needs to remove unwanted Optional Chaining.
For easy JSON manipulation in Swift you could try this little library. It seems pretty easy and you could do this:
var dictionary: [String: AnyObject]!
if let json = NKJSON.parse(yourNSDataObject) {
dictionary <> json[NKJSON.rootKey]
}
First confirm that the response which you are getting is in json format or in string format.
For json parsing you can use swifty json pod

Resources