簡體   English   中英

在 Swift 中解碼 JSON 時出現“數據無法讀取,因為它丟失”錯誤

[英]“The data couldn’t be read because it is missing” error when decoding JSON in 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 並且正確設置了它的目標。

謝謝

打印error.localizedDescription具有誤導性,因為它僅顯示毫無意義的通用錯誤消息。

所以永遠不要在Decodable catch 塊中使用localizedDescription

以簡單的形式

print(error)

它顯示了完整的錯誤,包括關鍵信息debugDescriptioncontext Decodable錯誤非常全面。


例如,在開發代碼時,您可以分別捕獲每個可Decodable錯誤

} catch let DecodingError.dataCorrupted(context) {
    print(context)
} catch let DecodingError.keyNotFound(key, context) {
    print("Key '\(key)' not found:", context.debugDescription)
    print("codingPath:", context.codingPath)
} catch let DecodingError.valueNotFound(value, context) {
    print("Value '\(value)' not found:", context.debugDescription)
    print("codingPath:", context.codingPath)
} catch let DecodingError.typeMismatch(type, context)  {
    print("Type '\(type)' mismatch:", context.debugDescription)
    print("codingPath:", context.codingPath)
} catch {
    print("error: ", error)
}

它只顯示最重要的信息。

我剛剛解決了一個類似的問題,但對於屬性列表解碼器。

這種情況下的錯誤似乎意味着未找到密鑰而不是整個數據。

嘗試將結構中的變量設為可選,它應該在問題所在的地方返回一個 nil 值。

嘗試打印實際錯誤而不僅僅是描述。 它應該給你一條消息,比如"No value associated with key someKey (\\"actual_key_if_you_defined_your_own\\")." ,這比localizedDescription有用得多。

“無法讀取數據,因為它丟失了”

來自此代碼的錯誤:

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

因為:似乎密鑰丟失或輸入錯誤。

您可以通過如下編碼來檢查缺少哪個鍵

...catch {
    debugPrint(error)
}

注意:如果結構鍵與 JSON 數據鍵不同,請參見下面的示例:結構中的鍵是“title”,而數據中的鍵是“name”。

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

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

如果你輸入錯誤'name',錯誤會彈出。

此外,如果您輸入錯誤此“CodingKeys”,您將收到錯誤消息。

enum CodingKeys:...

剛剛有同樣的錯誤。 我在解碼器的手動代碼中出錯。 在我的代碼屬性中, 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)
}

首先使屬性可選然后

如果您的情況與此類似,請嘗試使用decodeIfPresent

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM