ios 致命错误:无法从应用程序包中解码productsTest.json

pw136qt2  于 12个月前  发布在  iOS
关注(0)|答案(2)|浏览(164)

它表示"Build Succeeded"。然而,在画布上,它写着"Could not view this file - crashed"。APP也崩溃了。
来自JSONDecoder.swift的问题

Thread 1: Fatal error: Failed to decode productsTest.json from app bundle.

内容视图(文件名:ContentView.swift)

struct ContentView: View {

    let menu = Bundle.main.decode([ProductSection].self, from: "productsTest.json")
    
    var body: some View {
        
        NavigationView{
            
            VStack{
                List {
                    ForEach(menu) { section in
                        Text(section.category)
                    }
                }
            }.navigationTitle("Products")
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

可编码的扩展来解码json(文件名:JSONDecoder.swift)

extension Bundle {

    func decode<x: Decodable>(_ type: x.Type, from filename: String) -> x {
        guard let json = url(forResource: filename, withExtension: nil) else {
            fatalError("Failed to locate \(filename) in app bundle.")
        }

        guard let jsonData = try? Data(contentsOf: json) else {
            fatalError("Failed to load \(filename) from app bundle.")
        }

        let decoder = JSONDecoder()

        guard let result = try? decoder.decode(x.self, from: jsonData) else {
            fatalError("Failed to decode \(filename) from app bundle.")
        }

        return result
    }
}

引导阅读JSON的Swift文件(文件名:ProductsTest.swift)

struct ProductSection: Codable, Identifiable {
    var id: UUID
    var category: String
    var items: [ItemList]
}

struct ItemList: Codable, Equatable, Identifiable {
    var id: UUID
    var status: String
    var quantity: Int
    var name: String
    var price: Double
    var image: String
    var moreImage: [String]
    var productCode: String
    var UPCCode: String
    var servingSize: String
    var servingPerContainer: String
    var amountPerServing: [String]
    var percentageDailyValue: String
    var description: [String]
    var suggestedUse: String
    var otherIngredients: [String]
    var warning: [String]

    #if DEBUG
    static let example = ItemList(
        id: UUID(),
        status: "in-stock",
        quantity: 10,
        name: "Doctor's Best, Vitamin D3, 25 mcg (1,000 IU), 180 Softgels",
        price: 4.98,
        image: "753950002098.front",
        moreImage: ["753950002098.back"],
        productCode: "DRB-00209",
        UPCCode: "753950002098",
        servingSize: "1 Softgel",
        servingPerContainer: "180 servings",
        amountPerServing: ["Vitamin D3: 25 mcg (1000 IU)"],
        percentageDailyValue: "125%",
        description: ["Empty, Empty"],
        suggestedUse: "Adult Use: Take 1 softgel daily with food, or as recommended by a nutritionally-informed physician.",
        otherIngredients: ["Extra virgin olive oil; softgel capsule (bovine gelatin; glycerin; purified water)"],
        warning: ["Store in a cool dry place."]
    )
    #endif
}

JSON文件(已验证)(文件名:productsTest.json)

[
    {
        "id": "EF1CC5BB-4785-4D8E-AB98-5FA4E00B6A66",
        "category": "SUPPLEMENT",
        "items": [
            {
                "id": "EDCD038C-036F-4C40-826F-61C88CD84DDD",
                "status" : "in-stock",
                "quantity" : 10,
                "name": "Doctor's Best, Vitamin D3, 25 mcg (1,000 IU), 180 Softgels",
                "price" : 4.98,
                "image" : "753950002098.front",
                "moreImage": ["753950002098.back"],
                "productCode" : "DRB-00209",
                "UPCCode" : "753950002098",
                "servingSize" : "1 Softgel",
                "servingPerContainer" : "180 servings",
                "amountPerServing" : ["Vitamin D3: 25 mcg (1000 IU)"],
                "percentageDailyValue" : "125%",
                "description" : ["Empty, Empty"],
                "suggestedUse" : "Adult Use: Take 1 softgel daily with food, or as recommended by a nutritionally-informed physician.",
                "otherIngredients" : ["Extra virgin olive oil; softgel capsule (bovine gelatin; glycerin; purified water)"],
                "warning" : ["Store in a cool dry place."]
                
            },
            {
                "id": "36A7CC40-18C1-48E5-BCD8-3B42D43BEAEE",
                "status" : "in-stock",
                "quantity" : 5,
                "name": "Now Foods, High Potency Vitamin D-3, 50 mcg (2000 IU), 120 Softgels",
                "price" : 4.26,
                "image" : "733739003676.front",
                "moreImage": ["733739003676.back"],
                "productCode" : "NOW-00367",
                "UPCCode" : "753950002098",
                "servingSize" : "1 Softgel",
                "servingPerContainer" : "120 servings",
                "amountPerServing" : ["Vitamin D4: 50 mcg (2000 IU)"],
                "percentageDailyValue" : "250%",
                "description" : ["Empty, Empty"],
                "suggestedUse" : "Take 1 softgel daily with a meal.",
                "otherIngredients" : ["Extra virgin olive oil and softgel capsule (bovine gelatin; water; glycerin)., Not manufactured with yeast; wheat; gluten; soy; corn; milk; egg; fish or shellfish ingredients. Produced in a GMP facility that processes other ingredients containing these allergens."],
                "warning" : ["For adults only, Consult physician if pregnant/nursing; taking medication; or have a medical condition. Keep out of reach of children, Natural color variation may occur in this product, Store in a cool, dry place after opening."]
            }
        ]
    },
    {
        "id": "3D97FAB4-50AC-40FC-9BF0-3F46BB6A92F5",
        "category": "ELECTRONICS",
        "items": [
            {
                "id": "empty",
                "status" : "empty",
                "quantity" : 0,
                "name": "empty",
                "price" : 0.00,
                "image" : "empty",
                "moreImage": ["empty"],
                "productCode" : "empty",
                "UPCCode" : "empty",
                "servingSize" : "empty",
                "servingPerContainer" : "empty",
                "amountPerServing" : ["empty"],
                "percentageDailyValue" : "empty",
                "description" : ["empty"],
                "suggestedUse" : "empty",
                "otherIngredients" : ["empty"],
                "warning" : ["empty"] 
            }
        ]
    }
]

崩溃控制台报告

...
Exception Type:        EXC_BAD_INSTRUCTION (SIGILL)
Exception Codes:       0x0000000000000001, 0x0000000000000000
Exception Note:        EXC_CORPSE_NOTIFY

Termination Signal:    Illegal instruction: 4
Termination Reason:    Namespace SIGNAL, Code 0x4
Terminating Process:   exc handler [4837]

Application Specific Information:
JOCO/DecodeJson.swift:23: Fatal error: Failed to decode products.json from app bundle.
...
zz2j4svz

zz2j4svz1#

你几乎不应该使用try?-它只会丢弃错误。如果不能用更好的方式处理错误,至少应该捕获并打印错误;至少你知道哪里出了问题。
将JSON解码更改为:

extension Bundle {
    
    func decode<x: Decodable>(_ type: x.Type, from filename: String) -> x? {
        guard let json = url(forResource: filename, withExtension: nil) else {
            print("Failed to locate \(filename) in app bundle.")
            return nil
        }
        do {
            let jsonData = try Data(contentsOf: json)
            let decoder = JSONDecoder()
            let result = try decoder.decode(x.self, from: jsonData)
            return result
        } catch {
            print("Failed to load and decode JSON \(error)")
            return nil
        }
    }
}

会给你一个错误
加载和解码JSON数据失败Corrupted(Swift.DecodingError.Context(codingPath:[_JSONKey(stringValue:“Index 1”,intValue:1),CodingKeys(stringValue:“items”,intValue:nil),_JSONKey(stringValue:“索引0”,intValue:0)、CodingKeys(stringValue:“id”,intValue:nil)],debugDescription:“尝试从无效的UUID字符串解码UUID。",underlyingError:(无))
这直接指向了问题-外部数组的第二个元素(索引1)中的第一个item(索引0)有一个无效的id-果然,它有一个“空”的id-不能转换为UUID。因此,要么修复数据,要么将id的类型更改为String

e7arh2l6

e7arh2l62#

由于编辑队列,我重新发布它与补充(从Reading in a JSON File Using Swift):
像这样使用它:

let data = loadJson(file: "translations")

Swift 4.x和5.x使用Decodable

struct ResponseData: Decodable {
    var person: [Person]
}
struct Person : Decodable {
    var name: String
    var age: String
    var employed: String
}

func loadJson(filename fileName: String) -> [Person]? {
    if let url = Bundle.main.url(forResource: fileName, withExtension: "json") {
        do {
            let data = try Data(contentsOf: url)
            let decoder = JSONDecoder()
            let jsonData = try decoder.decode(ResponseData.self, from: data)
            return jsonData.person
        } catch {
            print("error:\(error)")
        }
    }
    return nil
}
  • Swift 3酒店,纽约**
func loadJson(filename fileName: String) -> [String: AnyObject]? {
    if let url = Bundle.main.url(forResource: fileName, withExtension: "json") {
        do {
            let data = try Data(contentsOf: url)
            let object = try JSONSerialization.jsonObject(with: data, options: .allowFragments)
            if let dictionary = object as? [String: AnyObject] {
                return dictionary
            }
        } catch {
            print("Error!! Unable to parse  \(fileName).json")
        }
    }
    return nil
}

P.S.如果你想用它来加载任何扩展名的文件,请将func loadJson body从let url = Bundle.main.url(forResource: fileName, withExtension: "json")改为let url = Bundle.main.url(forResource: fileName, withExtension: nil),并像这样使用它:

let data = loadJson(file: "translations.any_extension")

P.P.S.此外,为了提高可读性,将func loadJson重命名为decode

相关问题