"无法读取数据,因为它缺失了#34;在Swift

时间:2017-10-26 16:42:56

标签: ios json swift

我收到以下错误:

无法读取数据,因为它已丢失。

当我运行以下代码时:

struct Indicator: Decodable {
    let section: String
    let key: Int
    let indicator: Int
    let threshold: Int
}
    var indicators = [Indicator]()

    do {
        if let file = Bundle.main.url(forResource: "indicators", withExtension: "json") {
            indicators = try JSONDecoder().decode([Indicator].self, from: try Data(contentsOf: file))
        }
    } catch {
        print(error.localizedDescription)
    }

这些都是一个功能,但为了清楚起见,我删除了它们。我有一个代码块,它在一个不同的文件中非常相似(我从那里复制了这段代码并基本上改了名字)所以我不确定它为什么会发生。 json文件是有效的json,并且正确设置了目标。

由于

6 个答案:

答案 0 :(得分:26)

我刚刚解决了类似的问题但是对于属性列表解码器。

这种情况下的错误似乎意味着找不到密钥,而不是整个数据。

尝试在struct可选中设置变量,并且应该在问题所在的位置返回一个nil值。

答案 1 :(得分:22)

尝试打印实际错误而不仅仅是描述。它应该为您提供"No value associated with key someKey (\"actual_key_if_you_defined_your_own\")."之类的消息,它比localizedDescription更有用。

答案 2 :(得分:14)

打印error.localizedDescription会产生误导,因为它仅显示了非常没有意义的通用错误消息。

因此切勿在{{1​​}}捕获块中使用localizedDescription

以简单形式

Decodable

它显示了完整的错误,包括关键信息print(error) debugDescriptioncontext错误非常全面。


在开发代码时,例如,您可以分别捕获每个Decodable错误

Decodable

它仅显示最重要的信息。

答案 3 :(得分:2)

刚刚有同样的错误。我在解码器的手动代码中出错。在我的代码属性中,completedOn 是可选的,但我在解码时使用了 try 而不是 try?。当 json 中缺少该值时,该属性的解码将失败。请参阅下面的代码以更好地理解我的意思。

public var uuid: UUID
public var completedOn: Date?

...

required public convenience init(from decoder: Decoder) throws {
    self.init()

    let container = try decoder.container(keyedBy: CodingKeys.self)
    self.uuid = try container.decode(UUID.self, forKey: .uuid)
    self.completedOn = try? container.decode(Date.self, forKey: .completedOn)
}

答案 4 :(得分:0)

“由于缺少数据而无法读取数据”

此代码产生的错误:

...catch {
    print(error.localizedDescription)
}

原因:似乎密钥丢失或输入错误。

您可以通过以下编码来检查缺少哪个键

...catch {
    debugPrint(error)
}

注意:如果结构键与JSON数据键不同,请参见以下示例: struct中的键是“ title”,而数据中的键是“ name”。

struct Photo: Codable {
    var title: String
    var size: Size

    enum CodingKeys: String, CodingKey
    {
        case title = "name"
        case size
    }
}

如果您输错“名称”,则会弹出错误。

此外,如果您错误键入此“ CodingKeys”,则会收到错误消息。

enum CodingKeys:...

答案 5 :(得分:0)

首先将属性设为可选,然后

如果您的情况与此类似,请尝试此 decodeIfPresent

    `public init(from decoder: Decoder) throws {
    let container = try decoder.container(keyedBy: CodingKeys.self)
    firstName = try container.decodeIfPresent(String.self, forKey: .firstName)
    }`