解析JSON(如果包含数组)时出错

时间:2018-10-06 13:54:43

标签: json swift

我正在解析一个以数组格式返回数据的URL,如下所示:

[
{"_id":"5bb8b6038fb09210e09fd5c6","name":"John","city":"Dallas","country":"USA","__v":0},{"_id":"5bb8b6258fb09210e09fd5c7","name":"Robert","city":"SFO","country":"USA","__v":0}
]

我写了如下模型课:

class Peoples: Codable{
    let peoples:[People]
    init(peoples:[People]) {
        self.peoples = peoples
    }
}

class People: Codable{
    var _id : String
    var name : String
    var city : String
    var country : String
    var __v : Int

    init(
        _id : String,
        name : String,
        city : String,
        country : String,
        __v : Int
    )
    {
        self._id = _id
        self.name = name
        self.city = city
        self.country = country
        self.__v = __v

    }
}

我正在使用JSONDecoder解析JSON数据。

class HomeTabController: UIViewController ,UITableViewDataSource,UITableViewDelegate {
    private var varPeoples= [People]()

    override func viewDidLoad() {
        super.viewDidLoad()

        guard let url = URL(string: “<SomeURL>“)else {return}
        guard  let downloadURL = url else { return }

        URLSession.shared.dataTask(with: downloadURL) { data, urlResponse, error in
            guard let data = data, error == nil, urlResponse != nil
               else
               {
                print( "Something is wrong in URL")
                return;
               }
            print(data)
            do{
                let pplList=  JSONDecoder().decode(Peoples.self, from: data). // This line is giving data incorrect format error.
                self.varPeoples = pplList.peoples

                DispatchQueue.main.async{
                    self.tableView.reloadData()
                }
            }catch{
                print( error.localizedDescription)
            }
     }
}

如果JSON数据没有数组[],则可以解析它。但是我的URL返回带有数组[]符号的数据。所以任何人都可以修复代码。

2 个答案:

答案 0 :(得分:1)

您拥有的json是People而不是Peoples的数组:

do {
    let pplList =  try JSONDecoder().decode([People].self, from: data) // This line is giving data incorrect format error.
    print("pplList =", pplList)
} catch {
    print( error.localizedDescription)
}

答案 1 :(得分:1)

发生错误是因为,如果根对象是实现伞形结构的数组,则会破坏解码过程。

只需解码数组即可。

一些一般的 Decoding 注释:

  • 如果在大多数情况下JSON是只读的,则struct就足够了。
  • 如果JSON是只读的,则符合Decodable就足够了。
  • 如果JSON是只读的,则将结构成员声明为常量(let)。
  • 强烈建议添加CodingKeys以将 weird 键转换为符合Swift命名约定的(更具描述性的)名称。
  • 即使对象是一个类,也不必编写初始化程序,Decodable提供了一个初始化程序。
  • 为避免单数复数混淆,请以单数形式(struct)命名Person,并以复数形式(people)命名数组。语义上people中的每个对象代表一个Person
  • 捕获error.localizedDescription错误时
  • 从不打印DecodinglocalizedDescription返回通用字符串,但不返回实际错误描述。始终打印整个error实例。

struct Person: Decodable {

    private enum CodingKeys: String, CodingKey { case id = "_id", name, city, country, somethingMoreDescriptiveThan__v = "__v"}

    let id : String
    let name : String
    let city : String
    let country : String
    let somethingMoreDescriptiveThan__v : Int
}

...

private var people = [Person]()

...

do {
   self.people = JSONDecoder().decode([Person].self, from: data)
   DispatchQueue.main.async{
      self.tableView.reloadData()
   }
} catch {
   print(error)
}