triff
triff

Reputation: 157

Save object to json files

I have objects that I would like to write to a json file.

My code:

struct ChangeTime : Codable {
    let second : Int?
    let year : Int?
    let month : Int?
    let hourOfDay : Int?
    let dayOfMonth : Int?
    let minute : Int?
}

struct Inspirations : Codable {
    let avikoSegmentyRynku : [String]?
    let id : Int?
    let code : String?
    let avikoOkazjeJedzenia : [String]?
    let peopleCount : String?
    let productCodes : String?
    let langVersions : [LangVersions]?
}

struct InspiracjeProdukty : Codable { // main
    let products : [Products]?
    let inspirations : [Inspirations]?
}

struct Lang : Codable {
    let pL : String?
    let name : String?
    let active : Bool?
    let id : Int?
    let code : String?
}


struct LangVersions : Codable {
    let ingredients : String?
    let parentId : Int?
    let name : String?
    let preparation : String?
    let id : Int?
    let advice : String?
    let lang : Lang?
    let active : Bool?
    let dostepnaMobilnie : Bool?
    let favorite : Bool?
}

struct Products : Codable {
    let prepDeepFryer : String?
    let shelfLife : String?
    let avikoPodSegmentyRynku : [String]?
    let fat : Double?
    let markedAsFavourite1 : Bool?
    let kcal : Int?
    let shelfLifeTimeFrame : String?
    let active : Bool?
    let langVersions : [LangVersions]?
    let changeTime : ChangeTime?
    let prepMicrowave : String?
    let proteins : Double?
    let prepCombisteamer : String?
    let id : Int?
    let inPieces : Bool?
    let code : String?
    let eanBox : String?
    let containsGluten : Bool?
    let packageContents : Double?
    let layerPallet : Int?
    let palletWeight : Double?
    let name : String?
    let avikoConcepts : [String]?
    let kj : Int?
    let noBox : Int?
    let markedAsFavourite3 : Bool?
    let sunFlower : Bool?
    let eanFoil : String?
    let weightYieldPercent : Int?
    let avikoSegmentyRynku : [String]?
    let carbohydrates : Double?
    let prepPot : String?
    let markedAsFavourite2 : Bool?
    let palletHeight : Double?
    let contentPerBox : Int?
    let avikoWorlds : [String]?
    let avikoSegments : [String]?
    let regions : [Int]?
    let prepOven : String?
    let prepFryingPan : String?
    let boxLayer : Int?
}

func checkProductsStartFiles(path: URL) {
        guard let gitUrl = URL(string: path.absoluteString) else { return }
        URLSession.shared.dataTask(with: gitUrl) { (data, response
            , error) in
            guard let data = data else { return }
            do {
                let decoder = JSONDecoder()
                let jsonData = try decoder.decode(InspiracjeProdukty.self, from: data)
                //print(jsonData)
                if (jsonData.products?.count)! > 0  && (jsonData.inspirations?.count)! > 0 {
                    self.saveTempToFinnalFiles(jsonData: jsonData)
                }
            } catch let err {
                self.errorLoginMessage(txt: "\(ErrorsLabels.MainViewControler03). \(err)", title: "Blad".localized())
            }
            }.resume()
}

func saveTempToFinnalFiles(jsonData: InspiracjeProdukty){
        do {
            let productsToFile = try JSONSerialization.jsonObject(with: jsonData.products) as? [String: Any]
            let inspirationsToFile = try JSONSerialization.jsonObject(with: jsonData.inspirations) as? [String: Any]

            let documentsDir = FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask).first!

            try productsToFile.write(to: documentsDir.appendingPathComponent(selectedLanguage + "/json/products.json"))
            try inspirationsToFile.write(to: documentsDir.appendingPathComponent(selectedLanguage + "/json/inspirations.json"))

            print("XXXX")
            debugPrint(jsonData)
            //removeFile(path: path)
            //EZLoadingActivity.hide()
        } catch {
            print("Error deserializing JSON: \(error)")
        }
    }

In function: saveTempToFinnalFiles - I would like to save these 2 tables with objects to separate files: products.json and inspirations.json. In the line:

let productsToFile = try JSONSerialization.jsonObject (with: jsonData.products) as? [String: Any]
let inspirationsToFile = try JSONSerialization.jsonObject (with: jsonData.inspirations) as? [String: Any]

I'm getting an error:

Can not invoke 'jsonObject' with an argument list of type '(with: [Products]?)' / Cannot invoke 'jsonObject' with an argument list of type '(with: [Inspirations]?)'

Does anyone know how to fix it?

Upvotes: 2

Views: 144

Answers (3)

Scriptable
Scriptable

Reputation: 19750

Your main issue here is that you are trying to create a JSON Object from a JSON Object. To write this data to a file, you should be creating JSON Data.

JSONSerialization.data(withJSONObject: jsonData.products, options: nil)

But, as you are using the codable protocol, you should be using JSONEncoder instead.

let productsData = try JSONEncoder().encode(jsonData.products)

Then you can write this data directly to a file on the filesystem using the writeTo methods you are using above.

Upvotes: 0

Abdelahad Darwish
Abdelahad Darwish

Reputation: 6067

you can't use json object with type Product just convert to data using codable

jsonObject(with: Data, options: JSONSerialization.ReadingOptions = [])

saveTempToFinnalFiles:

func saveTempToFinnalFiles(jsonData: InspiracjeProdukty){


        if let product = try? JSONEncoder().encode(jsonData.products)  , let inspirations =  try? JSONEncoder().encode(jsonData.inspirations) {


            do{

            let documentsDir = FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask).first!

            try product.write(to: documentsDir.appendingPathComponent("selectedLanguage" + "/json/products.json"))
            try inspirations.write(to: documentsDir.appendingPathComponent("selectedLanguage" + "/json/inspirations.json"))

    } catch {
        print("Error deserializing JSON: \(error)")
    }
}
}

Upvotes: 0

Jigar
Jigar

Reputation: 1821

Try this code

func saveTempToFinnalFiles(jsonData: InspiracjeProdukty){
        do {
            let productsToFile = try JSONEncoder().encode(jsonData.products)

            let inspirationsToFile =  try JSONEncoder().encode(jsonData.inspirations)

            let documentsDir = FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask).first!

            try productsToFile.write(to: documentsDir.appendingPathComponent(selectedLanguage + "/json/products.json"))
            try inspirationsToFile.write(to: documentsDir.appendingPathComponent(selectedLanguage + "/json/inspirations.json"))

            print("XXXX")
            debugPrint(jsonData)
            //removeFile(path: path)
            //EZLoadingActivity.hide()
        } catch {
            print("Error deserializing JSON: \(error)")
        }
    }

Upvotes: 2

Related Questions