为什么我无法在 Swift 中解码我的 JSON 文件?

Why can't I decode my JSON file in Swift?

我将原始 JSON 文件分成两个不同的 JSON 文件,但现在我无法解码第二个文件。我已经 运行 通过了多个验证器,它似乎是有效的 JSON,并且我尝试将某些属性设为可选,但无济于事。

这是我用来解码的扩展,它适用于第一个文件,但对第二个文件崩溃并显示消息 "Thread 1: Fatal error: Failed to decode justiceforvictims.json from bundle."

    import UIKit

extension Bundle {
func decode<T: Decodable>(_ type: T.Type, from file: String) -> T {
    guard let url = self.url(forResource: file, withExtension: nil) else {
        fatalError("Failed to locate \(file) in bundle.")
    }

    guard let data = try? Data(contentsOf: url) else {
        fatalError("Failed to load \(file) from bundle.")
    }

    let decoder = JSONDecoder()

    guard let loaded = try? decoder.decode(T.self, from: data) else {
        fatalError("Failed to decode \(file) from bundle.")
    }

    return loaded
}
}

这些是描述 JSON 个文件的结构:

    struct petitionLabel: Codable, Identifiable {
    var id: String
    var name: String
    var items: [petitionName]
}

struct petitionName: Codable, Equatable, Identifiable {
    var id: String
    var name: String
    var link: String
    var organization: String?
    var justiceForVictims: Bool
    var policyReform: Bool
    var description: String?

#if DEBUG
static let example = petitionName(id: "45", name: "Hi", link: "bye", organization: "6", justiceForVictims: true, policyReform: false, description: "HI")
#endif
}

我这样调用单独的文件:

     let petitionlabelPolicyReform = Bundle.main.decode([petitionLabel].self, from: "petitions.json")
let petitionlabelJusticeForVictims = Bundle.main.decode([petitionLabel].self, from: "justiceforvictims.json")

这是有故障的 JSON 文件:

{
"id": "DE58CEFF-7023-4B60-88CC-80C5B7BFB6EC",
"name": "Justice for Victims",
"items": [
    {
        "id": "D44AAEBC-BF4F-42CD-8C37-0FEF772A5B69",
        "name": "Justice for Breonna Taylor",
        "link": "https://act.colorofchange.org/sign/justiceforbre-breonna-taylor-officers-fired",
        "organization": "Color of Change",
        "justiceForVictims": true,
        "policyReform": false,
        "description": "Hi"
    },
    {
        "id": "82B28AFF-BB29-4186-AA07-04959180D81A",
        "name": "Justice for Ahmaud Arbery",
        "link": "https://change.org/p/federal-bureau-of-investigation-disbarment-of-george-e-barnhill",
        "organization": "Change.org",
        "justiceForVictims": true,
        "policyReform": false,
        "description": "Disbar prosecutor George E. Barnhill for his decision to sit on the case of Ahmaud Arbery's murder for three months out of prejudice/racism and a personal relationship with the murderers."
    },
    {
        "id": "71B872F2-3B5D-46D0-9D98-E696B4AE30E4",
        "name": "Justice for Regis Korchinski-Paquet",
        "link": "https://change.org/p/justice-for-regis-korchinski-paquet",
        "organization": "Change.org",
        "justiceForVictims": true,
        "policyReform": false,
        "description": "Hold the officers involved accountable in the death of Regis Korchinski-Paquet through firing and filing charges."
    },
    {
        "id": "71B872F2-3B5D-4",
        "name": "Justice for Emerald Black",
        "link": "https://www.change.org/p/san-leandro-police-deartment-justice-for-emerald-black",
        "organization": "Change.org",
        "justiceForVictims": true,
        "policyReform": false,
        "description": ""
    },
    {
        "id": "71B872F2-3B5D-46",
        "name": "Justice for Tete Gulley",
        "link": "http://chng.it/44DyFp8kdv",
        "organization": "Change.org",
        "justiceForVictims": true,
        "policyReform": false,
        "description": ""
    },
    {
        "id": "71B87",
        "name": "Justice for Tamir Rice",
        "link": "http://chng.it/sZkTD8tQbb",
        "organization": "Change.org",
        "justiceForVictims": true,
        "policyReform": false,
        "description": ""
    },
    {
        "id": "71B872F",
        "name": "Justice for Chrystul Kizer",
        "link": "http://chng.it/kMVf2HnDkb",
        "organization": "Change.org",
        "justiceForVictims": true,
        "policyReform": false,
        "description": ""
    },
    {
        "id": "71B872F2-3B",
        "name": "Justice for Alejandro Vargas Martinez",
        "link": "http://chng.it/q9BwVvN6ZX",
        "organization": "Change.org",
        "justiceForVictims": true,
        "policyReform": false,
        "description": ""
    },
    {
        "id": "71B87534B",
        "name": "Justice for Jennifer Jeffley",
        "link": "http://chng.it/QNGzSzmzxr",
        "organization": "Change.org",
        "justiceForVictims": true,
        "policyReform": false,
        "description": ""
    },
    {
        "id": "71B872F4q35B",
        "name": "Justice for Young Uwa",
        "link": "http://chng.it/KG2Xd46gV4",
        "organization": "Change.org",
        "justiceForVictims": true,
        "policyReform": false,
        "description": ""
    },
    {
        "id": "71B87349",
        "name": "Justice for Belly Mujinga",
        "link": "http://chng.it/TBfm476Ysj",
        "organization": "Change.org",
        "justiceForVictims": true,
        "policyReform": false,
        "description": ""
    },
    {
        "id": "71B872F3425B",
        "name": "Justice for Jamee Johnson",
        "link": "https://campaigns.organizefor.org/petitions/justice-for-jamee-johnson",
        "organization": "Change.org",
        "justiceForVictims": true,
        "policyReform": false,
        "description": ""
    },
    {
        "id": "71B872253F23B",
        "name": "Justice for Collins Khosa",
        "link": "http://chng.it/TCsXxK5hkF",
        "organization": "Change.org",
        "justiceForVictims": true,
        "policyReform": false,
        "description": ""
    },
    {
        "id": "71B879002F2B",
        "name": "Justice for Cameron Green",
        "link": "http://chng.it/2tpznJ9btJ",
        "organization": "Change.org",
        "justiceForVictims": true,
        "policyReform": false,
        "description": ""
    },
    {
        "id": "711230jB",
        "name": "Justice for Sean Reed",
        "link": "http://chng.it/nV9KQGSxfc",
        "organization": "Change.org",
        "justiceForVictims": true,
        "policyReform": false,
        "description": ""
    },
    {
        "id": "71B872F2kfsd-3B",
        "name": "Justice for Joao Pedro",
        "link": "http://chng.it/FjJ7ZD4q5p",
        "organization": "Change.org",
        "justiceForVictims": true,
        "policyReform": false,
        "description": ""
    },
    {
        "id": "7kjlfgas1B872F2-3B",
        "name": "Justice for Willie Simmons",
        "link": "https://www.change.org/p/alabama-governor-kay-ivey-willie-simmons-has-served-38-years-for-a-9-robberyf",
        "organization": "Change.org",
        "justiceForVictims": true,
        "policyReform": false,
        "description": ""
    },
    {
        "id": "7B872Fkdfsg2-3B",
        "name": "Justice for Kendrick Johnson",
        "link": "https://www.change.org/p/united-states-supreme-court-justice-for-kendrick-johnson",
        "organization": "Change.org",
        "justiceForVictims": true,
        "policyReform": false,
        "description": ""
    },
    {
        "id": "7gijsa",
        "name": "Free Kyjuanzi Harris",
        "link": "https://www.change.org/p/illinois-governor-correcting-a-wrongful-conviction-kyjuanzi-harris",
        "organization": "Change.org",
        "justiceForVictims": true,
        "policyReform": false,
        "description": ""
    },
    {
        "id": "7aglkjB",
        "name": "Justice for Darrius Stewart",
        "link": "https://www.change.org/p/donald-j-trump-justice-for-darrius-stewart",
        "organization": "Change.org",
        "justiceForVictims": true,
        "policyReform": false,
        "description": ""
    },
    {
        "id": "71Bgsfklj3B",
        "name": "Justice for Andile Mchunu",
        "link": "https://www.change.org/p/bheki-cele-justice-for-andile-mchunu-bobo",
        "organization": "Change.org",
        "justiceForVictims": true,
        "policyReform": false,
        "description": ""
    },
    {
        "id": "7sdfgjkl1",
        "name": "Justice for Amiya Braxton",
        "link": "https://www.change.org/p/bre-jackson-justice-for-amiya-braxton",
        "organization": "Change.org",
        "justiceForVictims": true,
        "policyReform": false,
        "description": ""
    },
    {
        "id": "7thooos1",
        "name": "Justice for Eric Riddick",
        "link": "https://www.change.org/p/free-eric-riddick",
        "organization": "Change.org",
        "justiceForVictims": true,
        "policyReform": false,
        "description": ""
    },
    {
        "id": "rkjsgf",
        "name": "Justice for Elijah Nichols",
        "link": "https://www.change.org/p/ralph-s-northam-justice-for-elijah-nichols",
        "organization": "Change.org",
        "justiceForVictims": true,
        "policyReform": false,
        "description": ""
    },
    {
        "id": "ekas",
        "name": "Justice for Zinedine Karabo Gioia",
        "link": "https://www.change.org/p/the-botswana-government-justice-for-zinedine",
        "organization": "Change.org",
        "justiceForVictims": true,
        "policyReform": false,
        "description": ""
    },
    {
        "id": "rjkgsd1",
        "name": "Retrial for Angel Bumpass",
        "link": "https://www.change.org/p/bill-lee-demand-a-retrial-for-angel-bumpass-wrongfully-convicted-13-year-old-with-a-life-sentence",
        "organization": "Change.org",
        "justiceForVictims": true,
        "policyReform": false,
        "description": ""
    },
    {
        "id": "lkjas1",
        "name": "Justice for Sheku Bayoh",
        "link": "https://www.change.org/p/police-scotland-investigate-the-death-of-sheku-bayoh-in-police-custody",
        "organization": "Change.org",
        "justiceForVictims": true,
        "policyReform": false,
        "description": ""
    },
    {
        "id": "kadgskjldx",
        "name": "Free Albert Wilson",
        "link": "https://www.change.org/p/everybody-free-albert-wilson-from-the-crooked-kansas-legal-system",
        "organization": "Change.org",
        "justiceForVictims": true,
        "policyReform": false,
        "description": ""
    },
    {
        "id": "fjdiobs",
        "name": "Justice for Amari Boone",
        "link": "https://www.change.org/p/greg-abbott-justice-for-amari-boone",
        "organization": "Change.org",
        "justiceForVictims": true,
        "policyReform": false,
        "description": ""
    },
    {
        "id": "34asklj",
        "name": "Justice for Rashad Cunningham",
        "link": "https://www.change.org/p/fox-news-justice-for-rashad-cunningham-%EF%B8%8F",
        "organization": "Change.org",
        "justiceForVictims": true,
        "policyReform": false,
        "description": ""
    },
    {
        "id": "34jklasf",
        "name": "Justice for Tazne Vank Wyk",
        "link": "https://www.change.org/p/goodwood-magistrate-s-court-justice-for-tazne-van-wyk",
        "organization": "Change.org",
        "justiceForVictims": true,
        "policyReform": false,
        "description": ""
    },
    {
        "id": "3gjkaf4",
        "name": "Free Marshae Jones",
        "link": "https://www.change.org/p/pleasant-grove-police-department-dismiss-the-charges-on-marshae-jones-and-charge-the-one-who-shot-her-and-her-unborn-babyF",
        "organization": "Change.org",
        "justiceForVictims": true,
        "policyReform": false,
        "description": ""
    },
    {
        "id": "3agkjfn4",
        "name": "Justice for Michael Dean",
        "link": "https://www.change.org/p/temple-police-department-justice-for-michael-dean",
        "organization": "Change.org",
        "justiceForVictims": true,
        "policyReform": false,
        "description": ""
    },
    {
        "id": "3kgraljn4",
        "name": "Justice for Dion Johnson",
        "link": "https://www.change.org/p/phoenix-police-department-justice-for-dion-johnson",
        "organization": "Change.org",
        "justiceForVictims": true,
        "policyReform": false,
        "description": ""
    },
    {
        "id": "3jgakbfn4",
        "name": "Justice for Tamla Horsford",
        "link": "https://www.change.org/p/state-of-georgia-fire-sheriff-ron-freeman-stop-his-corruption-and-constant-cover-ups-as-sheriff-in-forsyth-count",
        "organization": "Change.org",
        "justiceForVictims": true,
        "policyReform": false,
        "description": ""
    },
    {
        "id": "3agllll4",
        "name": "Justice for Shukri Abdi",
        "link": "https://www.change.org/p/manchester-police-justice-for-shukri-abdi",
        "organization": "Change.org",
        "justiceForVictims": true,
        "policyReform": false,
        "description": ""
    },
    {
        "id": "3rasthe",
        "name": "Free Chaffin Darnel",
        "link": "https://www.change.org/p/everyone-and-the-police-of-cooks-county-illinois-free-chaffin-darnel-y",
        "organization": "Change.org",
        "justiceForVictims": true,
        "policyReform": false,
        "description": ""
    },
    {
        "id": "34t3409etj",
        "name": "Justice for Cariol Horne",
        "link": "https://www.change.org/p/nys-comptroller-thomas-p-dinapoli-support-former-buffaloe-police-officer-cariol-horne-to-receive-her-pension-a7acf769-f001-4a37-8fcc-558023abc33a",
        "organization": "Change.org",
        "justiceForVictims": true,
        "policyReform": false,
        "description": ""
    },
    {
        "id": "33c094",
        "name": "Justice for Brittany Williams",
        "link": "https://www.change.org/p/drop-false-charges-placed-on-police-brutality-victim-and-hold-the-officers-accountable",
        "organization": "Change.org",
        "justiceForVictims": true,
        "policyReform": false,
        "description": ""
    },
    {
        "id": "3j94g4",
        "name": "Justice for Quentin Suttles",
        "link": "https://www.change.org/p/john-j-flynn-consequences-for-excessive-force-used-on-quentin-suttles",
        "organization": "Change.org",
        "justiceForVictims": true,
        "policyReform": false,
        "description": ""
    },
    {
        "id": "8gkw47",
        "name": "Free Kenneth Reams",
        "link": "https://www.change.org/p/amnesty-international-free-kenneth-reams-he-s-been-on-death-row-for-the-past-26-years-he-never-killed-anybody",
        "organization": "Change.org",
        "justiceForVictims": true,
        "policyReform": false,
        "description": ""
    },
    {
        "id": "8lj7",
        "name": "Justice for James Scurlock",
        "link": "https://www.change.org/p/douglas-county-attorney-donald-kleine-demand-justice-for-james-scurlock-killed-by-omaha-racist-during-george-floyd-protest",
        "organization": "Change.org",
        "justiceForVictims": true,
        "policyReform": false,
        "description": ""
    },
    {
        "id": "8gh7",
        "name": "Justice for David McAtee",
        "link": "https://www.change.org/p/louisville-mayor-greg-fischer-justice-for-david-mcatee",
        "organization": "Change.org",
        "justiceForVictims": true,
        "policyReform": false,
        "description": ""
    },
    {
        "id": "8jgarl7",
        "name": "Justice for Ashton Dickson",
        "link": "https://www.change.org/p/mayor-of-ottawa-justice-for-ashton-dickson-he-was-killed-at-the-age-of-25-and-had-a-bright-future-ahead",
        "organization": "Change.org",
        "justiceForVictims": true,
        "policyReform": false,
        "description": ""
    },
    {
        "id": "8graijeo7",
        "name": "Free Anthony Wint",
        "link": "https://www.change.org/p/ron-desantis-free-anthony-wint-fbc27c7c-920d-4104-9960-a234f45cbe20",
        "organization": "Change.org",
        "justiceForVictims": true,
        "policyReform": false,
        "description": ""
    },
    {
        "id": "8iba7",
        "name": "Retrial for Sandra Bland",
        "link": "https://www.change.org/p/texas-governor-i-want-sandra-bland-s-case-reopened",
        "organization": "Change.org",
        "justiceForVictims": true,
        "policyReform": false,
        "description": ""
    },
    {
        "id": "9igrae0",
        "name": "Justice for Brad Levi",
        "link": "https://www.change.org/p/city-of-austin-texas-justice-for-brad-levi-ayala",
        "organization": "Change.org",
        "justiceForVictims": true,
        "policyReform": false,
        "description": ""
    },
    {
        "id": "9lkgjra0",
        "name": "Justice for Jonas Joseph",
        "link": "https://www.change.org/p/tampa-bay-justice-for-jonas-joseph",
        "organization": "Change.org",
        "justiceForVictims": true,
        "policyReform": false,
        "description": ""
    },
    {
        "id": "9afdgj0",
        "name": "Justice for Dominique Clayton",
        "link": "https://www.change.org/p/justice-for-dominique-clayton",
        "organization": "Change.org",
        "justiceForVictims": true,
        "policyReform": false,
        "description": ""
    },
    {
        "id": "90ntk0",
        "name": "Justice for Anderson Arboleda",
        "link": "https://www.change.org/p/fiscaliacol-justicia-para-anderson-arboleda-joven-afro-asesinado-a-golpes-por-un-polic%C3%ADa-en-el-cauca-justiciaparaandersonarboleda-policiacolombia-cgr-colombia-pgn-col-defensoriacol",
        "organization": "Change.org",
        "justiceForVictims": true,
        "policyReform": false,
        "description": ""
    },
    {
        "id": "9bej90",
        "name": "Free Curtis Price",
        "link": "https://www.change.org/p/governor-of-south-carolina-south-carolina-supreme-court-south-carolina-senators-free-curtis-price",
        "organization": "Change.org",
        "justiceForVictims": true,
        "policyReform": false,
        "description": ""
    },
    {
        "id": "90vw0",
        "name": "Justice for Crosley Green",
        "link": "https://www.change.org/p/grant-clemency-to-crosley-green-now",
        "organization": "Change.org",
        "justiceForVictims": true,
        "policyReform": false,
        "description": ""
    },
    {
        "id": "9b90ea0",
        "name": "Justice for Tyler J. Evans",
        "link": "https://www.change.org/p/columbia-county-jail-justice-for-tyler-j-evans",
        "organization": "Change.org",
        "justiceForVictims": true,
        "policyReform": false,
        "description": ""
    }
]
}

问题是您的顶级 json 类型是类型 petitionLabel 而不是数组 [petitionLabel] 的对象。所以这不是 SwiftUI.

的问题

因此您需要更改

let petitionlabelJusticeForVictims = Bundle.main.decode([petitionLabel].self, from: "justiceforvictims.json")

let petitionlabelJusticeForVictims = Bundle.main.decode(petitionLabel.self, from: "justiceforvictims.json")

正如我在 https://www.tutorialspoint.com/compile_swift_online.php

中的测试代码中所做的那样
import Foundation
import Glibc

let str = """
{
"id": "DE58CEFF-7023-4B60-88CC-80C5B7BFB6EC",
"name": "Justice for Victims",
"items": [
    {
        "id": "D44AAEBC-BF4F-42CD-8C37-0FEF772A5B69",
        "name": "Justice for Breonna Taylor",
        "link": "https://act.colorofchange.org/sign/justiceforbre-breonna-taylor-officers-fired",
        "organization": "Color of Change",
        "justiceForVictims": true,
        "policyReform": false,
        "description": "Hi"
    }
]
}
"""

struct petitionLabel: Codable {
    var id: String
    var name: String
    var items: [petitionName]
}

struct petitionName: Codable {
    var id: String
    var name: String
    var link: String
    var organization: String?
    var justiceForVictims: Bool
    var policyReform: Bool
    var description: String?

#if DEBUG
static let example = petitionName(id: "45", name: "Hi", link: "bye", organization: "6", justiceForVictims: true, policyReform: false, description: "HI")
#endif
}

let json = try JSONDecoder().decode(petitionLabel.self, from: str.data(using: .utf8)!)

print(json)

为了您的方便,最好捕获 JSONDecoder.decode 抛出的函数错误,而不是使用 try? 将其静音,这样您就可以记录错误。实际上,使用 try! 可以帮助您理解错误,因为 Swift 会像这样向您报告错误:

Fatal error: Error raised at top level: Swift.DecodingError.typeMismatch(Swift.Array<Any>, Swift.DecodingError.Context(codingPath: [], debugDescription: "Expected to decode Array<Any> but found a dictionary instead.", underlyingError: nil))

我只是忘了在 JSON 周围加上括号 lol