Home > Blockchain >  Error Parsing Swift in nested JSON (JSON Serilization)
Error Parsing Swift in nested JSON (JSON Serilization)

Time:10-10

 if(UserDefaults.standard.string(forKey: "UID") != nil){
                guard let dataFile = Bundle.main.path(forResource: "database7", ofType: "json"),
                      let database = FileManager.default.contents(atPath: dataFile) else {
                    fatalError("Data not found")
                }
                let json = try? JSONSerialization.jsonObject(with: database, options: [])
                if let json = json as? [String: Any] {
                    if let jsonChild = json["tired"] as? [[String: Any]] {
                        for botanical in jsonChild {
                            var botanicalObject = BotanicModel(json: botanical)
                            botanicDetail.append(botanicalObject)
                          print(botanicDetail)
                        }
                        
                    }
                } else{
                    fatalError("Failed to parse json")
                }
                
                
            }

So I'm trying to parse my local data but it's throwing the error and I could not figure it out; I couldn't retrieve any Data and the Data is a bit too complex to figure out on its own.

Below is the Model

 struct BotanicModel {

    var id: ID
  
    init(id: ID ){
        self.id = id
    }
    
    init(json: [String:Any]){
        self.id = ID(json: json["id"] as? [String:Any] ?? [:])
    }
}
struct ID {
    var name: String
    var therapeutic: [String]
    var clinical: [String]
    var contraindications: [String]
    var drugNutrient: [String]
    var chemical: [String]
    var toxicity: [String]
    
    init(name: String, therapeutic: [String], clinical: [String], contraindications: [String], drugNutrient: [String], chemical: [String], toxicity: [String]) {
        self.name = name
        self.therapeutic = therapeutic
        self.clinical = clinical
        self.contraindications = contraindications
        self.drugNutrient = drugNutrient
        self.chemical = chemical
        self.toxicity = toxicity
    }
    
    init(json: [String: Any]) {
        self.name = json["name"] as? String ?? "name"
        self.therapeutic = json["therapeutic"] as? [String] ?? []
        self.clinical = json["clinical"] as? [String] ?? []
        self.contraindications = json["contraindications"] as? [String] ?? []
        self.drugNutrient = json["drugNutrient"] as? [String] ?? []
        self.chemical = json["chemical"] as? [String] ?? []
        self.toxicity = json["toxicity"] as? [String] ?? []
    }
    
}

Data is given Below

{
   "tired": [
    {
        
        "id":[
        {
            "name":"Achillea millefolium (Yarrow)",
            "therapeutic":[
                "• Anodyne - due to prostaglandin-inhibiting action\n• Anti-inflammatory\n• Antiseptic\n• Antispasmodic\n• Astringent\n• Bitter tonic\n• Carminative\n• Cholagogue\n• Decongestant\n• Diaphoretic\nHot infusion - stimulating diaphoretic effect\nCold infusion - diuretic effect or tones gastric organs\n• Diuretic\n• Hemostatic\n• Hypotensive\n• Stimulant\n• Urinary antiseptic"
            ],
            "clinical":[
                "• Allergies\n• Dysmenorrhea\n• Hemorrhoids\n• Peptic ulcer\n• Antibacterial:\nGram positive bacteria\nGram negative bacteria\n• Circulatory disorders\n• Hemorrhaging disorders\n• Influenza and colds\n• Lacerations and puncture wounds - topically\n• Menorrhagia with uterine atony\n• Pain associated with pelvic disorders\n• Uterine spasms\n• Vaginitis with vaginal atony"
            ],
            "contraindications":[
                "• External use:\nContact dermatitis in sensitive individuals\n• Gastrointestinal inflammation:\nCrohn's disease\nIrritable bowel syndrome\nUlcerative colitis\n• Increased central nervous system function (CNS hyperfunction)\n• Pregnancy:\nDue to the emmenagogue and abortifacient effects"
            ],
            "drugNutrient":[
                "• Counterproductive to use medications that inhibit stomach acid production, ie antacids, gastric acid secretion inhibitors and histamine H2 receptor antagonists, since yarrow promotes stomach acid secretion"
            ],
            "chemical":[
                "• Achilleic acid (identical to aconitic acid)\n• Alkanes\n• Alkaloids:\nAchilleine\nBetonicine\nStachydrine\n• Apigenin, an antispasmodic agent\n• B-iso-thujone, see Toxicity\n• Betaine\n• Earthly ash consisting of nitrates, phosphates, and chlorides of potash and line\n• Fatty acids:\nLinoleic\nOleic\nPalmatic\n• Lactones\n• Potassium and calcium salts\n• Rutin\n• Salicylic acid (anti-inflammatory anodyne organic acid\n• Saponins\n• Sterols - Beta sitosterol\n• Succinic acid\n• Trigonelline\n• Volatile oils:\nAzulene\nCamphor\nCineol\nSabinene\nPinene"
            ],
            "toxicity":[
                "• B-iso-thujone can cause:\nVomiting\nStomach and intestinal cramps\nRetention of urine\n• Extreme cases with large doses:\nConvulsions\nRenal damage\nTremors\nVertigo"
            ]
        
        }
        ]
    }
    
    ]
    }

If you have any ideas to fix this problem please share them.

I don't know what to type. I have mentioned the whole problem but StackOverflow wants me to explain it in detail so I wrote this sentence.

CodePudding user response:

Your model structure is quite rigid because the top object is named "tired", which forces one variable to be named like that. Your JSON should actually be different if you are looking for different types of symptoms - for example, having "symptom : tired," on the top, followed by "herbs : [ { id:...".

Your JSON can be decoded using the following objects:

struct Tired: Codable {
    let tired: [HerbCollection]
}

struct HerbCollection: Codable {
    let id: [Herb]
}

struct Herb: Codable {
    let name: String
    let therapeutic: [String]
    let clinical: [String]
    let contraindications: [String]
    let drugNutrient: [String]
    let chemical: [String]
    let toxicity: [String]
}

Here's how to decode:

        do {
            let tired = try JSONDecoder().decode(Tired.self, from: Data(json.utf8))

            print(tired.tired[0].id[0].name)
            print(tired.tired[0].id[0].therapeutic[0])
            print(tired.tired[0].id[0].clinical[0])
            // etc.
        } catch {
            print(error)
        }
  • Related