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