Why wont my decoder parse .json files

launchdata.json:

[
    {
        "name": "Smartcard",
        "imageName": "Smartcard",
        "description": "A all new way to buy and sell stuff featuring RFID and NFC for touchless transactions and with local server you can pay with your phone.",
        "department": "Ticki Finance",
        "productid": 1737484,
        "id": 1,
        "creator": "The Ticki Team"
    },
    {
        "name": "Ink pad",
        "imageName": "Inkpad",
        "description": "A quick and easy way to take fingerprints and stamp stamps:), And with a quick water activation taking only 15 seconds you can setup in no time. Also, refilling the ink chamber is super easy, all you have to do is put ink in the middle hole.",
        "department": "Ticki Design",
        "productid": 7338388,
        "id": 2,
        "creator": "The Ticki Team"
    },
    {
        "name": "Wallet",
        "imageName": "Wallet",
        "description": "Ever had issues with your credit cards falling out of your pocket/wallet? Well this fixes any issues. Introducing Ticki Wallet. ",
        "department": "Ticki Finance",
        "productid": 2444495,
        "id": 3,
        "creator": "The Ticki Team"
    },
    {
        "name": "Pencil Case",
        "imageName": "PencilCase",
        "description": "I always lose my my pencils. How about you? Well i'm fixing that today with ticki pencil case. A pencil case that can hold pencils, an eraser, and of course, tickies.",
        "department": "Ticki Design",
        "productid": 3840398,
        "id": 4,
        "creator": "The Ticki Team"
    }
]

Load function:

func load<T: Decodable>(_ filename: String) -> T {
    guard let fileUrl = Bundle.main.url(forResource: filename, withExtension: nil) else {
        fatalError("Couldn't find \(filename) in main bundle.")
    }
    
    do {
        let data = try Data(contentsOf: fileUrl)
        let decoder = JSONDecoder()
        let decodedObject = try decoder.decode(T.self, from: data)
        return decodedObject
    } catch {
        fatalError("Couldn't parse \(filename) as \(T.self):\n\(error)")
    }
}

Error:

Thread 1: Fatal error: Couldn't parse Launchdata.json as Array<Product>:
dataCorrupted(Swift.DecodingError.Context(codingPath: [], debugDescription: "The given data was not valid JSON.", underlyingError: Optional(Error Domain=NSCocoaErrorDomain Code=3840 "Invalid value around line 1, column 0." UserInfo={NSDebugDescription=Invalid value around line 1, column 0., NSJSONSerializationErrorIndex=0})))

Replies

Could you show the actual T type with which you call load ?

I tested by creating a Type:

struct TickiItem: Codable {
    var name: String
    var imageName: String
    var description: String
    var department: String
    var productid: Int
    var id: Int
    var creator: String
}

and calling

let jsonString =
        """
        [
            {
                "name": "Smartcard",
                "imageName": "Smartcard",
                "description": "A all new way to buy and sell stuff featuring RFID and NFC for touchless transactions and with local server you can pay with your phone.",
                "department": "Ticki Finance",
                "productid": 1737484,
                "id": 1,
                "creator": "The Ticki Team"
            },
            {
                "name": "Ink pad",
                "imageName": "Inkpad",
                "description": "A quick and easy way to take fingerprints and stamp stamps:), And with a quick water activation taking only 15 seconds you can setup in no time. Also, refilling the ink chamber is super easy, all you have to do is put ink in the middle hole.",
                "department": "Ticki Design",
                "productid": 7338388,
                "id": 2,
                "creator": "The Ticki Team"
            },
            {
                "name": "Wallet",
                "imageName": "Wallet",
                "description": "Ever had issues with your credit cards falling out of your pocket/wallet? Well this fixes any issues. Introducing Ticki Wallet. ",
                "department": "Ticki Finance",
                "productid": 2444495,
                "id": 3,
                "creator": "The Ticki Team"
            },
            {
                "name": "Pencil Case",
                "imageName": "PencilCase",
                "description": "I always lose my my pencils. How about you? Well i'm fixing that today with ticki pencil case. A pencil case that can hold pencils, an eraser, and of course, tickies.",
                "department": "Ticki Design",
                "productid": 3840398,
                "id": 4,
                "creator": "The Ticki Team"
            }
        ]
        """

var myVar: [TickiItem] = []
let data = jsonString.data(using: .utf8, allowLossyConversion: false)
let jsonDecoder = JSONDecoder()
do {
    myVar = try jsonDecoder.decode([TickiItem].self, from: data!)
} catch {
    print("Decode error", jsonString)
}

So please show more code.

As you can see from Claude31's answer, your JSON contains an array so instead of

let decodedObject = try decoder.decode(T.self, from: data)

you need to:

let decodedObjects = try decoder.decode([T].self, from: data)
  • Unless T itself is an array, which is not told. Otherwise, load return which item from the file ?

  • True that.

Add a Comment

You may have also to change the signature of load, from

func load<T: Decodable>(_ filename: String) -> T {
}

to

func load<T: Decodable>(_ filename: String) -> [T] {
}
    var id: Int
    var productid: Int
    var name: String
    var description: String
    var department: Department
    var creator: String
    
    private var imageName: String
    
    var image: Image {
        Image(imageName)
    }
    
    enum Department: String, CaseIterable, Codable {
        case TickiFinance = "Ticki Finance"
        case TickiDesign = "Ticki Design"
        case TickiDev = "Ticki Developer"
    }
}```
  • @techboss_11123 WHere does this code fit ? What do you show here ? And you do not answer on what T is and if it's an array… So please explain more clearly.

Add a Comment