user1801745
user1801745

Reputation: 389

Value of type 'NSArray.Element' (aka 'Any') has no subscripts

I openned an old ios project in Xcode with warnings about swift 4 updates. During some fixing an error I could not find solution. The error occours while looping jsonArray, passing values to variables...

let url=NSURL(string:"http://webserver.com/json")
    let data = NSData(contentsOf: url! as URL)

    do {
        let jsonResult = try JSONSerialization.jsonObject(with: data! as Data, options: JSONSerialization.ReadingOptions.mutableContainers) as! NSDictionary
        let jsonArray = jsonResult.value(forKey: "person") as! NSArray

        for json in jsonArray {
            let id = json["id"] as? Int?
            let name = json["name"] as? String
            let age = json["age"] as? String

            tableID.append(String(id!))
            tableName.append(name!)
            tableAge.append(age!)

            tableView.reloadData()
        }

    } catch {

    }

Upvotes: 1

Views: 2451

Answers (1)

vadian
vadian

Reputation: 285072

There are many don'ts in the code.

  • NSURL, NSData
  • NSArray, NSDictionary (which causes the error)
  • (NS)Data(contentsOf)
  • value(forKey:)
  • .mutableContainers
  • ignoring the error in the catch block

The actual native Swift syntax is

let url = URL(string:"http://webserver.com/json")!
let task = URLSession.shared.dataTask(with: url) { [unowned self] (data, response, error) in
    if let error = error { print(error); return }

    do {
        if let jsonResult = try JSONSerialization.jsonObject(with: data!) as? [String:Any],
           let jsonArray = jsonResult["person"] as? [[String:Any]] {

           for json in jsonArray {
                let id = json["id"] as! Int
                let name = json["name"] as! String
                let age = json["age"] as! String

                self.tableID.append(String(id))
                self.tableName.append(name)
                self.tableAge.append(age)
            }
            DispatchQueue.main.async {
                self.tableView.reloadData()
            }      
        }

    } catch {
      print(error)
    }
}
task.resume()

There is one don't left: Don't use multiple arrays as data source.

Upvotes: 4

Related Questions