1

JSON response:

{
    "matches": [
        {
        "platformId": "EUW1",
        "gameId": 3427082245,
        "champion": 21,
        "queue": 450,
        "season": 9,
        "timestamp": 1511224973899,
        "role": "NONE",
        "lane": "MID"
        }
    ],
    "startIndex": 0,
    "endIndex": 1,
    "totalGames": 136
}

Serialization:

let myJsonMatchList = try JSONSerialization.jsonObject(with: content, options: JSONSerialization.ReadingOptions.mutableContainers) as! <Array<Dictionary<String,Any>>

Could not cast value of type __NSDictionaryM (0x10b693260) to NSArray (0x10b692dd8).

The problem is with the Array Dictionary String Any Replacing it with AnyObject works but it does not allow me to access anything from within, i.e other than to just print the raw Json.

What is the proper structure for this serialization because I am stuck?

Andy Jazz
  • 49,178
  • 17
  • 136
  • 220
  • 3
    I can clearly see that response json is a dictionary – Harish Pathak Nov 21 '17 at 10:32
  • http://roadfiresoftware.com/2016/12/how-to-parse-json-with-swift-3/ https://www.raywenderlich.com/150322/swift-json-tutorial-2 – Harish Pathak Nov 21 '17 at 10:33
  • "What to cast JSON response as in JsonSerialization for specific Json Response": From reading the JSON, it's obvious that the JSON is a Dictionary at top level. From reading the error message "Could not cast value of type __NSDictionaryM (0x10b693260) to NSArray (0x10b692dd8)." It's saying exactly the same thing, while you think it's an array. – Larme Nov 21 '17 at 10:37

1 Answers1

3

The JSON is an object, which maps to a Dictionary. The array is matches which is accessed from within the object.

so try this..

if let myJsonMatchList = try JSONSerialization.jsonObject(with: content, options: []) as? [String: Any] {
    if let arr = myJsonMatchList["matches"] as? [[String: Any]] {
         print(arr)
    }
}

Here is the code working in a playground

var str = "{\"matches\": [{\"platformId\": \"EUW1\",\"gameId\": 3427082245,\"champion\": 21,\"queue\": 450,\"season\": 9,\"timestamp\": 1511224973899,\"role\": \"NONE\",\"lane\": \"MID\"}],\"startIndex\": 0,\"endIndex\": 1,\"totalGames\": 136}"

var data = str.data(using: .utf8)
if let myJsonMatchList = try JSONSerialization.jsonObject(with: data!, options: []) as? [String: Any] {
    if let arr = myJsonMatchList["matches"] as? [[String: Any]] {
        print(arr)
    }
}
Scriptable
  • 19,402
  • 5
  • 56
  • 72
  • 1
    arr is an array, so you could do `arr.first` (to get the first item in the list) or `for item in arr { ... }`. Once you have a single item from the array you would use the same techniques. `let first = arr.first; let gameId = first["gameId"] as String` – Scriptable Nov 21 '17 at 10:55
  • It's going to be a very slow day I feel. –  Nov 21 '17 at 10:55
  • 2
    Please don't adopt that `.mutableContainers` nonsense. It's twice nonsense because #1 the result is assigned to a constant which is ***im**mutable* and #2 even without `.mutableContainers` you get mutability in Swift when assigning the result to a `var`iable. – vadian Nov 21 '17 at 11:38
  • @vadian agreed, answer was modified from OP's code but has now has that removed and no options set as they shouldn't be needed – Scriptable Nov 21 '17 at 11:52
  • 1
    Thank you. You can even omit the `options` parameter. – vadian Nov 21 '17 at 11:52