【问题标题】:FIXED: JSON cannot decode array from php修复:JSON 无法从 php 解码数组
【发布时间】:2019-10-30 04:55:53
【问题描述】:

JSON 解码器显示空列表,但所有内容均已正确编码。我从服务器得到一个 json 数组,在 Xcode 控制台中它仍然显示一个空数组。

News(news: [])

当来自服务器的当前响应是有效的 json 数组时:

{"news":[{"info_id":"unique id","title":"some title","description":"some description","date":"2019-07-10","time":"10:23:00"}]}

我解析 json 的结构是:

struct News: Codable {

let news = [Info]()

struct Info: Codable {

    let infoId: String
    let title: String
    let description: String
    let date: String
    let time: String

    private enum CodingKeys: String, CodingKey {
        case infoId = "info_id"
    }

}

}

我尝试使用该代码解码该帖子数组:

let decoder = JSONDecoder()
                let news: News = try decoder.decode(News.self, from: data)
                print("\(news)")

解决方案:let news = [Info]() 更改为 var news = [Info]()

【问题讨论】:

  • 好了,排序好了,我把 let news = [Info]() 改成了 var news = [Info]()。

标签: php ios json swift


【解决方案1】:

试试这个。

    struct BaseNews: Codable {
    let news: [News]
}

// MARK: - News
struct News: Codable {
    let infoID, title, newsDescription, date: String
    let time: String

    enum CodingKeys: String, CodingKey {
        case infoID = "info_id"
        case title
        case newsDescription = "description"
        case date, time
    }
}


let decoder = JSONDecoder()
let news: News = try decoder.decode(BaseNews.self, from: data)

更新:根据您的评论

解码时我无法将新闻投射到新闻,因为它可能是数组中的更多对象

Codables 协议需要在其主体内显式声明属性,因为您不能使用相同的密钥解码多个类型,或者缺少一个密钥,因此要么实现完整的 JSON 解码密钥,或浏览您的 json 数组切片或执行任何您需要的操作以获取所需数据的输出以进行解码。

现在通常当同一个数组中有多个对象类型时,应该有某种方法来判断哪个是什么,或者至少在对象之间有一个公共键和一个可为空的值,而不会丢失任何键。

还有一种高级解码实践,例如从它的解码器中重写符合方的初始化程序并手动创建一个容器并解码每个键,这将允许我们以我们喜欢的方式操作数据类型、键路径。

旁注:web api 返回一个被认为是不好的做法 包含多种对象类型的数组

【讨论】:

  • 解码时我无法将新闻投射到新闻,因为它可能是数组中的更多对象。我仍然在控制台中得到空数组:[]
  • 在 baseNews 结构中添加其他键
  • 当我删除数组中的初始化程序时会引发错误
  • @D.B.我试图为你解释,查看更新的答案
【解决方案2】:

您已经在结构中初始化[Info] 的数组,这就是您得到一个空数组的原因。你只需要改变

var news = [Info]()

var news: [Info]?

你的结构应该是这样的:

struct News: Codable {
    var news : [Info]
}

struct Info: Codable {

    var infoId: String?
    var title: String?
    var description: String?
    var date: String?
    var time: String?

    private enum CodingKeys: String, CodingKey {
        case infoId = "info_id"
    }

}

你可以走了。

【讨论】:

  • 它说“类型名称后的预期成员名称或构造函数调用”,这就是我这样做的原因。然后另一个警告'Type'Parties'不符合协议'Decodable'和Encodable。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-05-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多