Swift JSON Error: Failed to pass value of type "__NSDictionaryM" to "NSArray"

when decoding JSON from webservice (API) I get an error:

Could not cast value of type '__NSDictionaryM' (0x1037ad8a8) to 'NSArray' (0x1037ad470). 

My code is:

 var kGetURL = "http://bitnami.local/cscart_demo/api/users" //var kGetURL = "http://localhost/fendy/getjson.php" var json : Array<AnyObject> = [] override func viewDidLoad() { super.viewDidLoad() start() } func getData(data : NSData){ //error at this line : json = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as! Array<AnyObject> //error tableView.reloadData() } func start(){ var url : NSURL = NSURL(string: kGetURL)! var data : NSData = NSData(contentsOfURL: url)! getData(data) } 

if i change url to http: //localhost/fendy/getjson.php it works so well.

I get an error if my url is http: //bitnami.local/cscart_demo/api/users

Reply from webservice http: //localhost/fendy/getjson.php :

  [{"id":"17","Name":"KFC","Message":"awesome"}, {"id":"18","Name":"McDonald","Message":"good"}, {"id":"23","Name":"Burger King","Message":"tasty"}, {"id":"38","Name":"Pizza hut","Message":"yummy"}, {"id":"39","Name":"Steak","Message":"very Delicious"}] 

Reply from webservice http: //bitnami.local/cscart_demo/api/users :

  {"users": [{"user_id":"4","user_login":"user_4","is_root":"N","timestamp":"1441608048","user_type":"C","status":"A","firstname":"","lastname":"","email":" fendy.w@mvig.net ","company":"","company_id":"1","company_name":"Simtech"}, {"user_id":"3","user_login":"customer","is_root":"N","timestamp":"1441604240","user_type":"C","status":"A","firstname":"Customer","lastname":"Customer","email":" customer@example.com ","company":"Simtech","company_id":"1","company_name":"Simtech"}, {"user_id":"1","user_login":"admin","is_root":"Y","timestamp":"1441604240","user_type":"A","status":"A","firstname":"John","lastname":"Doe","email":" robby@mvig.net ","company":"Your company","company_id":"0","company_name":null}], "params":{"page":1,"items_per_page":"10","sort_order":"asc","sort_by":"name","sort_order_rev":"desc","total_items":"3"}} 

I think the style is the same, but why not work with the url http: //bitnami.local/cscart_demo/api/users . can anyone help?

+6
source share
2 answers

The bit response begins with { , and therefore it is a JSON object , which corresponds to NSDictionary . Another starts with [ , which indicates an array.

You need to change the json type to Dictionary<String, AnyObject> and deserialize as follows:

 json = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as! Dictionary<String, AnyObject> 
+4
source

Your method passes the JSON result to the array. It works fine with a URL that returns an array represented as JSON, but it doesn't work with a URL that returns a dictionary, not an array represented as JSON.

Although the "style" of the returned values ​​looks the same, the second is a dictionary with one element. You probably need to extract the "users" element from it, which is an array.

If you don't know which of the two URLs you are getting, can you try both styles with as? instead of as! :

 let tmp : AnyObject! = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) if let arr = tmp as? Array<AnyObject> { json = arr } else if dict = tmp as? [String: AnyObject] { json = dict["users"] as! Array<AnyObject> } else { // Handle an error: the input was unexpected } tableView.reloadData() 
0
source

All Articles