Osmiqa
Osmiqa

Reputation: 39

Why is my JSON file not being read by my code in swift?

My first time posting, sorry if it's a stupid question. I am trying to read and access this JSON file inside my Resources but I keep getting an error.

Here is the JSON:

{
    "teams": [{
            "team_id": 1,
            "team_name": "Lord",
            "units": [{
                    "unit_id": 1,
                    "unit_first_name": "Jaber",
                    "unit_last_name": "Jac",
                    "unit_distance_covered": 33,
                    "unit_active_minutes": 330
                }, {
                 
                    "unit_id": 2,
                    "unit_first_name": "Kayle",
                    "unit_last_name": "Bayle",
                    "unit_distance_covered": 40,
                    "unit_active_minutes": 200
                }]
                    
    }]
}
        

and here is my code that I have been trying:

import UIKit


struct Team: Decodable {
    
    var team_id: Int
    var team_name: String
    var units: [Units]
}
    
struct Units: Decodable {
    
    var unit_id: Int
    var unit_first_name: String
    var unit_last_name: String
    var unit_distance_covered: Int
    var unit_active_minutes: Int
}


guard let sourcesURL = Bundle.main.url(forResource: "Testing", withExtension: "json")
else {
    fatalError("Could not find Testing.json")
}

guard let competitionData = try? Data(contentsOf: sourcesURL)
else {
    fatalError("Could not convert data...")
}

let decoder = JSONDecoder()

guard let results = try? decoder.decode([Team].self, from: competitionData)

else {
    fatalError("There was a problem decoding the data")
}
print(results)

Here is the error code I recieve:

Fatal error: There was a problem decoding the data: file __lldb_expr_11/MyPlayground.playground, line 36
Playground execution failed:

error: Execution was interrupted, reason: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0).
The process has been left at the point where it was interrupted, use "thread return -x" to return to the state before expression evaluation.

* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
  * frame #0: 0x00007fff2f129044 libswiftCore.dylib`Swift._assertionFailure(_: Swift.StaticString, _: Swift.String, file: Swift.StaticString, line: Swift.UInt, flags: Swift.UInt32) -> Swift.Never + 532
    frame #1: 0x000000010f5b06ad $__lldb_expr12`main at playground11-4c4ea3..swift:0
    frame #2: 0x000000010c8b3150 MyPlayground`linkResources + 304
    frame #3: 0x00007fff2038c110 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__ + 12
    frame #4: 0x00007fff2038b524 CoreFoundation`__CFRunLoopDoBlocks + 434
    frame #5: 0x00007fff20385f34 CoreFoundation`__CFRunLoopRun + 899
    frame #6: 0x00007fff203856c6 CoreFoundation`CFRunLoopRunSpecific + 567
    frame #7: 0x00007fff2b76adb3 GraphicsServices`GSEventRunModal + 139
    frame #8: 0x00007fff24675187 UIKitCore`-[UIApplication _run] + 912
    frame #9: 0x00007fff2467a038 UIKitCore`UIApplicationMain + 101
    frame #10: 0x000000010c8b3212 MyPlayground`main + 194
    frame #11: 0x00007fff20256409 libdyld.dylib`start + 1
    frame #12: 0x00007fff20256409 libdyld.dylib`start + 1

I have been trying for more than 7 hours now with no hope in near sight. Please help 😊

Upvotes: 1

Views: 93

Answers (1)

gcharita
gcharita

Reputation: 8327

You should be able to decode this JSON by adding a struct that represents the top level object, like this:

struct MyData: Decodable {
    let teams: [Team]
}

Then you can call decode(_:from:) function passing MyData.self as type:

let decoder = JSONDecoder()
do {
    let results = try decoder.decode(MyData.self, from: competitionData)
    for team in results.teams {
        for unit in team.units {
            print(unit.unit_first_name)
        }
    }
} catch {
    print(error)
}

Upvotes: 1

Related Questions