Así que traté de analizar un archivo json y cuando lo analicé según la sintaxis, me da un error que no puede cambiar la cadena a una matriz de diccionario, pero cuando soluciono el problema, genera nil . alguien puede dar una opinion
func jsonFour() { let string = "[{\"address\": 7023000630,\"reportStatus\": \"Retrieved\",\"currentLocation\": {\"latitude\": 29.8529, \"longitude\": 73.99332,\"timestamp\": \"2019-01-07T16:35:25.079+05:30\"} }, {\"address\": 7290098339, \"reportStatus\": \"Retrieved\", \"currentLocation\": {\"latitude\": 21.628569, \"longitude\": 72.996956,\"timestamp\": \"2019-01-07T16:35:25.079+05:30\" } } ]" let data = string.data(using: .utf8)! do { if let jsonArray = try JSONSerialization.jsonObject(with: data, options : JSONSerialization.ReadingOptions.mutableContainers) as? [[ String : Any ]] { print(jsonArray) // use the json here let address = jsonArray["address"] as! [[String:Any]] if let timestamp = address["timestamp"] as? [String]{print(timestamp)} } else { print("bad json") } } catch let error as NSError { print(error) } } Cuando elimino los corchetes dobles de "String : Any" , funciona bien, pero no da ningún valor sino nil .
Y cuando procedo de esta manera, omite la declaración if y simplemente imprime "bad json" .
¿Qué estoy haciendo mal aquí?
Dado que hay Codable , le recomiendo encarecidamente que lo use en lugar de JSONSerialization .
Así que comience declarando sus estructuras para que coincidan con su estructura JSON
struct Model: Codable { var address: Int var reportStatus: String var currentLocation: Location } struct Location: Codable { var latitude, longitude: Double var timestamp: String } Ahora simplemente decodifique su JSON usando JSONDecoder
do { let data = string.data(using: .utf8)! let models = try JSONDecoder().decode([Model].self, from: data) } catch { print(error) } ... ahora models es una matriz de objetos Model y puedes trabajar con ellos.
Seguro que debe usar Codable para esto, pero para que su código se ejecute, use
let string = "[{\"address\": 7023000630,\"reportStatus\": \"Retrieved\",\"currentLocation\": {\"latitude\": 29.8529, \"longitude\": 73.99332,\"timestamp\": \"2019-01-07T16:35:25.079+05:30\"} }, {\"address\": 7290098339, \"reportStatus\": \"Retrieved\", \"currentLocation\": {\"latitude\": 21.628569, \"longitude\": 72.996956,\"timestamp\": \"2019-01-07T16:35:25.079+05:30\" } } ]" let data = string.data(using: .utf8)! do { if let jsonArray = try JSONSerialization.jsonObject(with: data) as? [[ String : Any ]] { jsonArray.forEach { if let add = $0["address"] as? Int , let currentLocation = $0["currentLocation"] as? [String:Any], let timestamp = currentLocation["timestamp"] as? String { print("address is : ", add ,"timestamp is : " , timestamp) } } } else { print("bad json") } } catch { print(error) }Tu problema obvio está aquí.
let address = jsonArray["address"] as! [[String:Any]] jsonArray es una matriz que no puede subíndice con ["address"]
Una matriz es una lista. Puede contener varios elementos. Tienes que usar un bucle para iterar una matriz (como en tu pregunta anterior )
address clave es Int (sin comillas dobles). El valor de la timestamp de tiempo de la clave es String y está en el diccionario para la currentLocation de la clave en la matriz
let data = Data(string.utf8) do { if let jsonArray = try JSONSerialization.jsonObject(with: data) as? [[String : Any]] { print(jsonArray) // use the json here for item in array { let address = item["address"] as! Int let currentLocation = item["currentLocation"] as! [String:Any] let timestamp = currentLocation["timestamp"] as! String print(timestamp) } } else { print("bad json") } } catch { print(error) } Nunca use .mutableContainers en Swift. Carece de sentido.