Ran Ran - 4 months ago 78
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)
task.resume()
}

func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, didReceiveData data: NSData) {
self.data.appendData(data);

}

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

}
func parseJSON() {

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


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


} catch let error as NSError {
print(error)
}
}

Answer

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

Comments