DavidVV
DavidVV

Reputation: 235

Swift JSON to Dictionary<String: Any>. Then cast "Any" as NSMutableArray

I am trying to read from a JSON String and draw a graph with its data:

{"y-axis-data":{"min":0.0,"max":1000,"Step":100.0},"x-labels":[1994,2000,2005],"y-values":[20,305,143]}

I wrote a function to create a dictionary from the string:

func jsonToDictionary(jsonString: String) -> [String: Any]? {

    if let jsonData: Data = jsonString.data(using: String.Encoding.utf8) {

        do {
            return try (JSONSerialization.jsonObject(with: jsonData, options: []) as? [String: Any])!
        } catch {
            some bla bla 
        }
    }
    return nil
}

The return dictionary should count 3 elements inside when I pass my JSON string, and it does.

I can then change of some variables (Double) which are 0 until now and give them the values of min max and Step from the "y-axis-data" key of my dictionary, using {"min":0.0,"max":1000,"Step":100.0} as a dictionary it self. Works fine.

My trouble comes when trying to initialize other atributes:

self.my_view!.x-labels = (jsonToDictionary!["x-labels"])  as? NSMutableArray

my_view has already been initialized as UIViewCustomClass(frame: someFrame)

myview.x-labels is an NSMutableArray and it is initialized as nil. After executing that line of code it is still nill, of course myview.x-labels.count is nil. if I do it this way:

self.my_view!.x-labels = (jsonToDictionary!["x-labels"])  as! NSMutableArray

I get a warning :

Treating a forced downcast to NSMutableArray as optional will never produce nil.

It then crashes on runtime with this error:

Could not cast value of type '__NSArrayI' (0x110ed5448) to 'NSMutableArray' (0x110ed4598).

of course the exact same thing happens with "y-values"

What is the right way to do this?

Upvotes: 0

Views: 400

Answers (2)

Cytus Chang
Cytus Chang

Reputation: 367

It was because your json!["x-labels"] is implicitly treated as NSArray, so you somehow had to do a "double-force-cast"

// get the converted json
let j = jsonToDictionary(jsonString: dict)
// double cast
let m = (j!["x-labels"] as! NSArray).mutableCopy() as! NSMutableArray

Result: enter image description here

Upvotes: 1

user2908517
user2908517

Reputation: 518

I think, JSONSerialization class converts into Array, and then Swift cannot cast Array to NSMutableArray. You can do this (Swift4):

let array = (jsonToDictionary!["x-labels"]) as? [Int]
if array != nil {
   self.my_view!.x-labels = NSMutableArray(array: array!)
}

Upvotes: 0

Related Questions