代码之家  ›  专栏  ›  技术社区  ›  Jacobo

将JSON中的对象解析和数组到Swift中的对象

  •  0
  • Jacobo  · 技术社区  · 6 年前

    嘿,我有以下JSON:

    {
        "monuments": [
            {
                "name": "Iglesia de Tulyehualco",
                "description": "No hay descripción",
                "latitude": 19.2544877,
                "longitude": -99.012157
            },
            {
                "name": "Casa de Chuyin",
                "description": "Casa de Jesús",
                "latitude": 119.2563629,
                "longitude": -99.0152632
            }
        ]
    }
    

    我得到下面的代码来尝试解析每个对象,但是得到的错误是Any类型没有成员“x”。

    func loadMonuments() {
        if let path = Bundle.main.path(forResource: "monuments", ofType: "json") {
            do {
                let data = try Data(contentsOf: URL(fileURLWithPath: path), options: .mappedIfSafe)
                let jsonResult = try JSONSerialization.jsonObject(with: data, options: .mutableLeaves)
                if let jsonResult = jsonResult as? Dictionary<String, AnyObject>, let monumentsJson = jsonResult["monuments"] as? [Any] {
                    for m in monumentsJson {
                        print(m)
                    }
                }
            } catch {
                // handle error
            }
        }
    }
    

    我想得到纪念碑的每一处财产。

    2 回复  |  直到 6 年前
        1
  •  2
  •   Shehata Gamal    6 年前

    选项1:

    struct Root:Decodable { 
     let monuments:[InnerItem] 
    }
    
    struct InnerItem:Decodable { 
     let name:String
     let description:String
     let latitude:Doube
     let longitude:Double 
    }
    

    //

     do {
          let data = try Data(contentsOf: URL(fileURLWithPath: path), options:[])
          let content = try JSONDecoder().decode(Root.self,from:data)
          print(content)
     }
     catch {
      print(error)
     }
    

    选项2:

    if let jsonResult = jsonResult as? [String:Any] , let monumentsJson = jsonResult["monuments"] as? [[String:Any]] {
         for m in monumentsJson {
             print(m["name"])
         }
    }
    
        2
  •  0
  •   Felipe Rolvar    6 年前

    年引入了Swift4 Codable 对于序列化,您必须尝试使对象可编码如下:

    struct Monument: Codable {
      let name: String
      let description: String
      let latitude: String
      let longitude: String
    }
    

    然后你可以用这个来解析这个对象:

    func loadMonuments() -> [Monument] {
        guard let path = Bundle.main.path(forResource: "monuments", ofType: "json"),
           let data = try Data(contentsOf: URL(fileURLWithPath: path), options: .mappedIfSafe)  else {
            return []
        }
    
        do {
            return try JSONDecoder().decode([Monument].self, from: data)
        } catch {
            print("error: \(error)")
            return []
        }
    }