jsonswiftparsingnested-json

Error Parsing JsonData in swift (JSON Serilization)


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.

 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")
                    }
                    
                    
                }

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"
                ]
            
            }
            ]
        }
        
        ]
        }

♾️♾️♾️♾️♾️♾️♾️♾️♾️♾️♾️♾️♾️♾️♾️♾️♾️♾️♾️♾️♾️♾️♾️♾️♾️♾️♾️♾️♾️♾️♾️♾️♾️♾️♾️♾️♾️♾️♾️♾️♾️♾️♾️


Solution

  • 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)
            }