Swift 4 and Alamofire - Type 'DataResponse' has no subscript members

Hi,
I have this code:

let params = ["parm": "getList",
                      "obj": "none"]

    Alamofire.request("http://nazwa.pl/", method: .get, parameters: params).responseJSON { responseData in
        if responseData.result.isSuccess {
            if((responseData.result.value) != nil) {
                let swiftyJsonVar = JSON(responseData.result.value!)

                var result = responseData
                print("result: \(responseData)")

                if let imieINazwisko = result["imieINazwisko"] as? String {
                    print("Imię i nazwisko: \(imieINazwisko)")
                }

            } else {
            }
        } else {
        }
    }

And my data:

{
  "ranking": {
    "id": 50971,
    "nazwa": "grupowy",
    "opis": "cx",
    "typ": "GRUPA",
    "dataWidoczneOd": {
      "year": 2018,
      "month": 2,
      "dayOfMonth": 1,
      "hourOfDay": 0,
      "minute": 0,
      "second": 0
    },
    "dataWidoczneDo": {
      "year": 2018,
      "month": 2,
      "dayOfMonth": 31,
      "hourOfDay": 0,
      "minute": 0,
      "second": 0
    },
    "dataOd": {
      "year": 2018,
      "month": 2,
      "dayOfMonth": 1,
      "hourOfDay": 0,
      "minute": 0,
      "second": 0
    },
    "dataDo": {
      "year": 2018,
      "month": 2,
      "dayOfMonth": 31,
      "hourOfDay": 0,
      "minute": 0,
      "second": 0
    },
    "idkiPlikowGrafiki": [
      "50976"
    ],
    "grupy": [
      {
        "id": 50981,
        "idkiPlikowGrafiki": [
          "50983",
          "50986"
        ],
        "kod": "ttt",
        "nazwa": "ttt",
        "gracze": []
      },
      {
        "id": 51032,
        "idkiPlikowGrafiki": [
          "51034"
        ],
        "kod": "yyy",
        "nazwa": "yyy",
        "gracze": [
          {
            "czasGry": "0 min",
            "liczbaZdobytychPunktow": "0.0",
            "email": "pawrilo@gmail.com",
            "zdjecieZFacebooka": "https://graph.facebook.com/1018655608235134/picture?width=200&height=150",
            "imieINazwisko": "Paweł Opała",
            "zakonczonaGra": false
          },
          {
            "czasGry": "0 min",
            "liczbaZdobytychPunktow": "0.0",
            "email": "lukasz.peta@icloud.com",
            "zdjecieZFacebooka": "https://graph.facebook.com/201192440635362/picture?width=200&height=150",
            "imieINazwisko": "Łukasz Betta",
            "zakonczonaGra": false
          }
        ]
      }
    ]
  }
}

i have problem with error. error: Type ‘DataResponse’ has no subscript members?

How can I repair it?

import UIKit

class DataResponse: CustomStringConvertible {

    var x = "{\"a\": 1, \"b\": 2}"

    var description: String {
        return x
    }

    func dostuff() {
        print("doing stuff")
    }
}

let dr = DataResponse()
print(dr)

Output:

{"a": 1, "b": 2}

Whoo! Hooo! That looks like a python dictionary (or ruby hash, or javascript object). Let’s subscript it!

print(dr["a"])

Output:

error: type ‘DataResponse’ has no subscript members

Lesson:

  1. Swift isn’t Python (or Ruby, or Javascript). In Swift, dictionaries look like this: ["b": 2, "a": 1]

  2. And strings aren’t dictionaries anyway:

    let str = "[\"a\": 1, \"b\": 2]" print(str)

    Output:

    ["a": 1, "b": 2]

Wooo! Hoo! That looks like a Swift dictionary. Let’s subscript it:

print(str["a"])

Output:

error: cannot subscript a value of type ‘String’ with an index of type ‘String’

@trifek Thanks very much for your question!

I think the problem is with the following line:

let swiftyJsonVar = JSON(responseData.result.value!)

Try changing it to:

let swiftyJsonVar = JSON(responseData.result.value!) as? [String: Any]

I would also encourage you to look at the following tutorial on our site on parsing JSON using Swift 4’s new Codable protocol. It really makes things a lot easier, and eliminates the need to use any third party libraries for JSON parsing :slight_smile:

I hope this helps!

All the best!

@trifek,
Do not get confused with all of the off-topic chatter. The answer to your problem lies with what @syedfa has suggested.

For an explanation on why that is the case,
In Swift you have a variable of type Any and it can hold literally any type, which is a good thing and a not so good thing because there is no automatic conversion. So when dealing with JSON, you have Array, Dictionary, Strings, Int, etc but unless specified they are Any, so you have to downcast them into a specific type.

A dictionary in swift is also called a key value pair, where again the key is a String where as the value could be anything (Any).

So you have to first convert the responseData into a dictionary with
let swiftyJsonVar = JSON(responseData.result.value!) as? [String:Any]

now you can access the swiftyJsonVar as a swift dictionary, if it is not castable into a dictionary as it could be an array, then it will fail so you must use proper guard or if statements to avoid errors.

cheers,

Jayant

This topic was automatically closed after 166 days. New replies are no longer allowed.