Learn Courses My Dashboard

Retrieving Data from JSON file

Trying to retrieve data from JSON file but when I enter Text(r.name), nothing happens. No error messages in my code, but my preview screen is blank. I’m 100% new to coding but I’m not getting any error messages in XCode and my build succeeds every time I hit command-B but the preview screen stays blank. Managed to lose a JSON file it took me hours to build in the process of trying to find the error so I am beyond frustrated.

It’s almost impossible to help without seeing some code. How are you reading the JSON into your code?

Hi Matt,

As Patrick is alluding to we would be able to guide you if you post your code. Rather than posting a screenshot, copy and paste your code in as text.

To format the code nicely, place 3 back-ticks ``` on the line above your code and 3 back-ticks ``` on the line below your code. The 3 back-ticks must be the ONLY characters on the line. The back-tick character is located on the same keyboard key as the tilde character ~ (which is located below the Esc key). You can also highlight an entire code block and click the </> button on the toolbar to wrap the block for you.

This also makes it easier for anyone assisting as they can copy the code and carry out some testing.

import SwiftUI

struct ListView: View {
   
 @ObservedObject var model = AgentModel()
    var body: some View {
        
        List(model.Agents) { r in
   
                Text(r.name)
            }

It’s literally the same as Module 2 Lesson 13 of the Recipe List app at the 28:40 mark. Like I was saying before, no error messages, and it builds every time, but the preview screen is blank.

We need to see the code that loads the JSON.

Not sure what you mean but here is code from my data service folder:

import Foundation

class DataService {

    
    static func getLocalData() -> [Agent] {
    
        let pathString = Bundle.main.path(forResource: "Agents", ofType: "json")
        
        guard pathString != nil else {
            return [Agent]()
            
        }
        
        let url = URL(fileURLWithPath: pathString!)
        
        do {
            
            let data = try Data(contentsOf: url)
            
            let decoder = JSONDecoder()

            
            do {
                
                let agentData = try decoder.decode([Agent].self, from: data)
                
                for r in agentData {
                    r.id = UUID()
                    
                }
                
                return agentData
            }
            
            catch {
                
                print(error)
            }
            
           
            
        }
        
        catch {

            print(error)
        }
        
        
     return[Agent]()
    }
    
}

OK, so how are you getting the decoded JSON data to your ListView?

Posted ListView and DataService code above. Will post all remaining code below.

Trying to make an app that will help with weight-based medication calculations for kids.

import SwiftUI

@main
struct MedsApp: App {
    var body: some Scene {
        WindowGroup {
            ListView()
        }
    }
}

From “Models” folder:

import Foundation

class Agent: Identifiable, Decodable {
    
    var id:UUID?
    var name:String
    var type:String
    var description:String
    var treatments:[String]
    var doseageForm:[String]
    var weightBasedDose:[String]
    var administration:[String]

}

From “ViewModels” folder:

import Foundation

class AgentModel: ObservableObject {
    
  @Published var Agents = [Agent]()
        
    init() {
        
        self.Agents = DataService.getLocalData()
    }
}

Anyone have any useful suggestions? Posted all my code but have not yet received any actual help…

Can you post a sample of the JSON you are using?

JSON excerpt…

[
 {
        "name": "Antibiotics",
        "dosageForm": [
            "Clindamycin: 75mg/5mL oral solution; 75mg, 150mg, and 300mg capsules; various IV solutions",
            "Ciprofloxacin: 500mg tablets, 250mg/5mL or 500mg/5mL oral solution; various IV solutions",
            "Doxycycline: 100mg tablets & capsules, 25mg/5mL or 50mg/5mL oral solution are most common oral forms; 100mg IV solution",
            "Meropenem: 500mg IV solution",
            "Linezolid: 100mg/5mL oral solution; 600mg oral tablets; 200mg/100mL and 600mg/300mL intravenous solutions"],
        "weightBasedDose": [
            "Clindamycin: Usual dosing is 10mg/kg to 20mg/kg per day PO (MAX DOSE 1.8 g/kg per day) OR 25mg/kg to 40mg/kg per day (MAX DOSE 2.7g/kg per day) IV in 3 to 4 divided doses",
            "Ciprofloxacin: 15mg/kg PO q12 or 10mg/kg IV q12 (MAX DOSE: 750mg per dose by mouth, 400mg per dose IV)",
            "Doxycycline: 2.2mg/kg",
            "Meropenem: 40mg/kg per dose IV q8 hours (MAX DOSE: 6 grams/day); for neonates <14 days postnatal age and <2kg, give 20mg/kg/dose q12; for neonates 15-28 days postnatal age and <2kg OR <14 days and >2kg, give 20mg/kg/dose q8; for neonates 29-60 days and <2kg OR 15-60 days and >2kg, give 30mg/kg/dose q8",
            "Linezolid: 10mg/kg/dose PO or IV q8 hours (MAX DOSE 600mg) for children <12 years;     600mg IV q12 hours for children >12 years old; for neonates <14 days postnatal age and <1kg OR neonates <7 days postnatal age and 1kg to 2kg, give 10mg/kg per dose IV q12; for neonates 15-28 days postnatal age and <1kg OR neonates 8-28 days postnatal age and >1kg, give 10mg/kg per dose IV q8"],
        "administration": [
            "Clindamycin: Orally or IV every 8 hours",
            "Ciprofloxacin: Orally or IV every 12 hours",
            "Doxycycline: Orally or IV every 12 hours",
            "Meropenem: Every 8 hours (see neonatal dosing regimen changes in weight-based dose column for exceptions)",
            "Linezolid: Orally or IV every 8 hours (see neonatal dosing regimen changes in weight-based dose column for exceptions)"],
          },
]

Couple things I notice right off the bat:

  1. This will fail because your Agent struct asks for keys that are not present in the JSON you supplied, namely: type, description and treatments.
  2. This will fail because your Agent struct asks for a key called doseageForm but the JSON you supplied has dosageForm.

If I comment out the first problem and rename the second, it works for me.

If you also make those corrections ad are still having issues, please let us know.

1 Like

Yeah like I said above, it’s an excerpt, I cut out type, description, and treatments for the purpose of posting here because they are extremely long. They are presents in the full JSON but I didn’t want to make a post dozens of pages long.

Thanks for catching the spelling error though.

When seeking help on a JSON decoding issue, always include enough data to decode a complete struct. Two or three would actually be preferable if the data isn’t too much.

Same goes for any issue, really. Always post all the code necessary to reproduce the problem. If you can, slim things down to just enough code to reproduce the problem and cut out any parts that are unrelated.

You can’t expect anyone else to know what you have left out or supply extra info to make your examples work. Ideally, they should be able to just cut and paste your code and go from there.

So… has your issue gone away?

Nope. Fixed the spelling error but no change in result. Just a blank screen whenever I run a preview.

Then there must be something else in your code interfering. Using your code (with the two corrections I mentioned above), I got the expected result.

Maybe there is something else in your complete JSON file that is causing an error?

I mean all the code is exactly what’s posted above and I haven’t made any changes since posting so it must be the JSON.

Would you mind if I messaged you the entire JSON?

Full disclosure, I’m a veteran who specialized in medical countermeasures to weapons of mass destruction. The intent of my app was give healthcare providers and first responders information on how treat kids affected by WMDs. That’s why I excerpted the JSON earlier, because I was reluctant to post about that kind of thing.

Go for it. It might be a couple hours before I can take a look, as I’m heading out right now, but I’d be more than happy to do so.

Thanks, will message you shortly. Take all the time you need, I’m heading out soon as well and won’t get another chance to work on this until Thursday at the earliest.

OK, I used the complete JSON file that you sent me via PM and discovered that not all of your items have a description field, so that was throwing things off. Not sure why you weren’t seeing any errors; I got an error in the console that clued me in to what was wrong.

So there’s two ways you can handle this:

  1. Since this is a JSON file that you control, you can make sure that each item has a description field, or
  2. You can make the description property in your Agent struct an optional string.

Not knowing all the details of the data myself, I opted for the latter fix.

(I also changed to id property so that you don’t have to assign an id when you read in the JSON; one will be assigned automatically for you whenever an Agent is constructed.)

So I ended up with this:

class Agent: Identifiable, Decodable {
    let id = UUID()
    var name: String
    var type: String
    var description: String?
    var treatments: [String]
    var dosageForm: [String]
    var weightBasedDose: [String]
    var administration: [String]
}

And also removed these lines from DataService.getLocalData() since they would no longer be needed:

for r in agentData {
    r.id = UUID()    
}