【问题标题】:I want to start parsing json file in an specific position SWIFTUI我想在 SWIFTUI 的特定位置开始解析 json 文件
【发布时间】:2021-07-07 00:42:00
【问题描述】:

我有这个 json,我的意图是只获取“municipios”数组。

{
  "title": "Municipios de Pontevedra",
  "provincia": "Pontevedra",
  "codprov": "36",
  "metadescripcion": "Lista de municipios de la provincia de Pontevedra | Seleccionar un muncipio",
  "keywords": "Lista de municipios, Previsión meteorológica para los municipios de la provincia de Pontevedra , El tiempo",
  "municipios": [
    {
      "CODIGOINE": "36001000000",
      "ID_REL": "1360010",
      "COD_GEO": "36010",
      "CODPROV": "36",
      "NOMBRE_PROVINCIA": "Pontevedra",
      "NOMBRE": "Arbo",
      "POBLACION_MUNI": 2904,
      "SUPERFICIE": 4266,
      "PERIMETRO": 33435,
      "CODIGOINE_CAPITAL": "36001011101",
      "NOMBRE_CAPITAL": "O Pazo",
      "POBLACION_CAPITAL": "286",
      "HOJA_MTN25": "0262-2",
      "LONGITUD_ETRS89_REGCAN95": -8.31474568,
      "LATITUD_ETRS89_REGCAN95": 42.11276572,
      "ORIGEN_COORD": "Mapa",
      "ALTITUD": 113,
      "ORIGEN_ALTITUD": "MDT5",
      "DISCREPANTE_INE": 0
    },
    {
      "CODIGOINE": "36002000000",
      "ID_REL": "1360025",
      "COD_GEO": "36020",
      "CODPROV": "36",
      "NOMBRE_PROVINCIA": "Pontevedra",
      "NOMBRE": "Barro",
      "POBLACION_MUNI": 3705,
      "SUPERFICIE": 3763.6494,
      "PERIMETRO": 31578,
      "CODIGOINE_CAPITAL": "36002041301",
      "NOMBRE_CAPITAL": "Santo Antoniño",
      "POBLACION_CAPITAL": "426",
      "HOJA_MTN25": "0152-4",
      "LONGITUD_ETRS89_REGCAN95": -8.62642506,
      "LATITUD_ETRS89_REGCAN95": 42.55592981,
      "ORIGEN_COORD": "Mapa",
      "ALTITUD": 143,
      "ORIGEN_ALTITUD": "MDT5",
      "DISCREPANTE_INE": 0
    },...

我已尝试使用此代码,但由于数组存在问题,它给了我一个错误。我认为这应该是一个数组,但 json 是一个字典,因为它以 { 字符开头,对吗?

import Foundation

import Foundation
import SwiftUI

struct Municipio: Codable,Identifiable{
    let id = UUID()
    let NOMBRE: String
    let POBLACION_MUNI: Int
}

class apiCall {
    func getMunicipios(completion:@escaping ([Municipio]) -> ()) {
        guard let url = URL(string: "urltojson") else { return }
        URLSession.shared.dataTask(with: url) { (data, _, _) in
            let municipios = try! JSONDecoder().decode([Municipio].self, from: data!)
            print(municipios)
            
            DispatchQueue.main.async {
                completion(municipios)
            }
        }
        .resume()
    }
}

我的目的是获取“municipios”数组

【问题讨论】:

标签: arrays json parsing swiftui


【解决方案1】:

尝试将您的内容解码为 Result 结构而不是 [Municipio]

struct Result: Codable {
    var municipios: [Municipio]
    
    struct Municipio: Codable, Identifiable {
        let id = UUID()
        let NOMBRE: String
        let POBLACION_MUNI: Int
    }
}

所以你需要像这样解码:

let municipiosResult = try! JSONDecoder().decode(Result.self, from: data!)
// your municipios will be accessible like this:
let municipios = municipiosResult.municipios
print(municipios)

【讨论】:

    【解决方案2】:

    你不能只解码结构的内部而不解码外部。因此,您必须有一个可以处理整个 JSON 正文的数据结构。使用app.quicktype.io,它会生成这个结构:

    
    struct JSONBody: Codable {
        let title, provincia, codprov, metadescripcion: String
        let keywords: String
        let municipios: [Municipio]
    }
    
    struct Municipio: Codable {
        let codigoine, idRel, codGeo, codprov: String
        let nombreProvincia, nombre: String
        let poblacionMuni, superficie, perimetro: Int
        let codigoineCapital, nombreCapital, poblacionCapital, hojaMtn25: String
        let longitudEtrs89Regcan95, latitudEtrs89Regcan95: Double
        let origenCoord: String
        let altitud: Int
        let origenAltitud: String
        let discrepanteIne: Int
    
        enum CodingKeys: String, CodingKey {
            case codigoine = "CODIGOINE"
            case idRel = "ID_REL"
            case codGeo = "COD_GEO"
            case codprov = "CODPROV"
            case nombreProvincia = "NOMBRE_PROVINCIA"
            case nombre = "NOMBRE"
            case poblacionMuni = "POBLACION_MUNI"
            case superficie = "SUPERFICIE"
            case perimetro = "PERIMETRO"
            case codigoineCapital = "CODIGOINE_CAPITAL"
            case nombreCapital = "NOMBRE_CAPITAL"
            case poblacionCapital = "POBLACION_CAPITAL"
            case hojaMtn25 = "HOJA_MTN25"
            case longitudEtrs89Regcan95 = "LONGITUD_ETRS89_REGCAN95"
            case latitudEtrs89Regcan95 = "LATITUD_ETRS89_REGCAN95"
            case origenCoord = "ORIGEN_COORD"
            case altitud = "ALTITUD"
            case origenAltitud = "ORIGEN_ALTITUD"
            case discrepanteIne = "DISCREPANTE_INE"
        }
    }
    
    

    您可以通过执行以下操作来解码:

    func decode(jsonData: Data) {
        do {
            let body = try JSONDecoder().decode(JSONBody.self, from: jsonData)
            let municipos = body.municipios
            print(municipos)
        } catch {
            print(error)
        }
    }
    

    请注意,我使用的是do/try/catch 而不是try! -- 如果失败,try! 将崩溃,并且不会为您提供有关为什么崩溃的有用信息。

    【讨论】:

      【解决方案3】:

      谢谢你们,你们告诉我必须解析整个文档,这对我很有帮助。这是我完美运行的结果代码。

      struct JSONObject: Codable {
          let title: String
          let provincia: String
          let codprov: String
          let metadescripcion: String
          let keywords: String
          let municipios: [Municipio]
      }
      
      struct Municipio: Codable,Identifiable{
          let id = UUID()
          let CODIGOINE: String
          let NOMBRE: String
          let POBLACION_MUNI: Int
      }
      
      class Api {
          func getObject(completion:@escaping ([Municipio]) -> ()) {
              guard let url = URL(string: "https://www.el-tiempo.net/api/json/v2/provincias/36/municipios") else { return }
              URLSession.shared.dataTask(with: url) { (data, _, _) in
                  let objeto = try! JSONDecoder().decode(JSONObject.self, from: data!)
                  let municipios = objeto.municipios
                  print(municipios)
                  DispatchQueue.main.async {
                      completion(municipios)
                  }
              }
              .resume()
          }
      }
      

      【讨论】:

      • 不客气;)。您没有义务,但如果您使用答案左侧的向上标记对您认为有用的答案进行投票,那就太好了。您还可以将其中一个更适合您的答案标记为您问题的最终答案。同样,没有义务,谢谢!
      • 请务必查看我关于 try! 的注释——如果服务器返回意外结果,这将使您的应用程序崩溃。
      猜你喜欢
      • 2021-10-12
      • 1970-01-01
      • 1970-01-01
      • 2016-09-16
      • 2022-06-17
      • 2022-01-21
      • 2020-07-15
      • 1970-01-01
      • 2011-12-26
      相关资源
      最近更新 更多