'Parse JSON Data Array with Swift 4

I am using the following code. It only works if the JSON data does not start with a '[' character. It works fine for JSON data starting with a '{' character. There is a similar question here: Parsing JSON array in swift but most of the methods are deprecated and I was unable to get the code to work. Here is the JSON call I am using:

guard let json = (try? JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.mutableContainers)) as? [String: Any]        else {
    print("Error: Could not parse JSON!!!")
    return
}

I tried removing all options and using allowFragments and mutableLeaves among others. From what I understand mutableContainers is a default setting but I have been trying whatever I can. Any help or advice would be much appreciated.

Here is a sample of the JSON data I am working with:

{ "CREATED_BY" = "Domain\USER"; "CREATED_DATE" = "2011-09-30T15:00:13"; STATUS = U; "EMPLOYEE_NUMBER" = 039000292; "UPDATED_BY" = "Domain\USER""; "UPDATED_DATE" = "2014-08-02T13:22:01"; }



Solution 1:[1]

The issue is that the [] signifies that the json is an Array of objects, so you need to cast this to an array. You can do this by either casting it to [Any] or by casting it to an array of dictionaries (which is what it really is).

do {
    let json = try JSONSerialization.jsonObject(with: data, options: []) as? [Any]
    let json2 = try JSONSerialization.jsonObject(with: data, options: []) as? [[String: Any]] 
} catch {
    print("Error: Couldn't parse JSON. \(error.localizedDescription)")
}

So provided the following json to the above block:

let jsonString = """
    [{
        "id": "5",
        "name": "Test",
        "team1": "thingy team",
        "team2": "clicky team",
        "category": "4",
        "end_date": "1415217600",
        "cat_name": "new thingy",
        "team1_bets": 1,
        "team2_bets": 1
    }]
"""

you would end up with an output of the following:

let json = Optional([{
    "cat_name" = "new thingy";
    category = 4;
    "end_date" = 1415217600;
    id = 5;
    name = Test;
    team1 = "thingy team";
    "team1_bets" = 1;
    team2 = "clicky team";
    "team2_bets" = 1;
}])
let json2 = Optional([["team2_bets": 1, "name": Test, "id": 5, "team1_bets": 1, "team2": clicky team, "team1": thingy team, "category": 4, "cat_name": new thingy, "end_date": 1415217600]])

The main difference between the two is that the contents of json are an array of Any objects, which would then need to be cast to whatever data type you're working with. The json2 array is an array of dictionaries, which you would then need to cast the Any objects but you still have the keys available.

Solution 2:[2]

Then it may be an array

do {
    let json = try JSONSerialization.jsonObject(with: data) as? [Any] 
    print(json)
}
catch {
   print(error)
}

This [ ] means Array ---- > [Any]

while this { } means Dictionary -----> [String:Any]

Solution 3:[3]

let json = try JSONSerialization.jsonObject(with: data!) as? [NSDictionary]; //jsonArray
print(json![0].value(forKey: "name")!); //jsonObject

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2
Solution 3 a442509097