The problem is when there is incomplete data NSJSONSerialization.JSONObjectWithData
is crashing the application giving unexpectedly found nil while unwrapping an Optional value
error instead of informing us using NSError variable. So we are unable to prevent crash.
You can find code we are using below
var error:NSError? = nil
let dataToUse = NSJSONSerialization.JSONObjectWithData(receivedData, options: NSJSONReadingOptions.AllowFragments, error:&error) as NSDictionary
if error != nil { println( "There was an error in NSJSONSerialization") }
Till now we are unable to find a work around.
The problem is that you cast the result of the JSON deserialization before checking for an error. If the JSON data is invalid (e.g. incomplete) then
returns
nil
andwill crash.
Here is a version that checks for the error conditions correctly:
Remarks:
The JSON reading option
.AllowFragments
does not help here. Setting this option only allows that top-level objects that are not an instance ofNSArray
orNSDictionary
, for exampleYou can also do it in one line, with an optional cast
as?
:The disadvantage is that in the
else
case you cannot distinguish whether reading the JSON data failed or if the JSON did not represent a dictionary.For an update to Swift 3, see LightningStryk's answer.
Here is a Swift 2 extension you can use to deserialise only an NSDictionary:
Sorry I wasn't sure how to do a guard return to avoid creating the temporary 'd'.
Swift 3:
Updated for Swift 3
Swift 2
Swift 3 NSJSONSerialization sample (read json from file):
Usage
Result (log screenshot)