Ran Ran - 1 year ago 177
Swift Question

Swift NSJSONSerialization.JSONObjectWithData doesn't handle empty Data

I have a data downloader class that downloads data from mySQL server.
The problem I am having is when the result is null - the app crashes with error message

Could not cast value of type '__NSArray0' (0x105548918) to 'NSMutableArray' (0x105549c00).

class userDetailsDownloader: NSObject, NSURLSessionDataDelegate {

weak var delegate: getUserDetails!
var data : NSMutableData = NSMutableData()

func downloadUserDetails(userEmail: String) {

let urlPath: String = "http://intouchmobile.co/phpscripts/getuserpassword.php?email=\(userEmail)"
let url: NSURL = NSURL(string: urlPath)!
var session: NSURLSession!
let configuration = NSURLSessionConfiguration.ephemeralSessionConfiguration() //defaultSessionConfiguration()
session = NSURLSession(configuration: configuration, delegate: self, delegateQueue: nil)
let task = session.dataTaskWithURL(url)

func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, didReceiveData data: NSData) {


func URLSession(session: NSURLSession, task: NSURLSessionTask, didCompleteWithError error: NSError?) {
if error != nil
print("Failed to get password")
print("Password Received")

func parseJSON() {

var jsonResult: NSMutableArray = NSMutableArray()
var password: String!
var firstName: String!
var lastName: String!

jsonResult = try NSJSONSerialization.JSONObjectWithData(self.data, options:NSJSONReadingOptions.AllowFragments) as! NSMutableArray

} catch let error as NSError {

Answer Source

Don't say as! NSMutableArray. The term as! means "crash me", so you can hardly be surprised when you do crash. Say as? NSMutableArray. Test the result for nil. If it is nil, stop.

if let jsonResult = try NSJSONSerialization.JSONObjectWithData(self.data, options:NSJSONReadingOptions.AllowFragments) as? NSMutableArray {
    self.jsonResult = jsonResult

You may still have problems because this is never going to be a mutable array; it's just an array. So you might have to change it to:

if let jsonResult = try NSJSONSerialization.JSONObjectWithData(self.data, options:NSJSONReadingOptions.AllowFragments) as? NSArray {
    self.jsonResult = NSMutableArray(array: jsonResult)

(But, as vadian has said in a comment, it would be even better if you could abandon use of NSArray and NSMutableArray and use Swift types instead.)

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download