Home > Mobile >  How can I read and write from/to a JSON file in a specific file path in swift?
How can I read and write from/to a JSON file in a specific file path in swift?

Time:03-18

I'm trying implementing a data manager singleton class reading/write from a JSON file but I obtain this error:

'self' used in method call 'LoadData' before all stored properties are initialized

this is the code:

import SwiftUI
import Combine

class DataManager: ObservableObject {
        
    static let shared = DataManager()
    
    var TTDItemMainList: TTDItemList = TTDItemList(itemList: [TTDItem(id: UUID(), itemDesc: "", itemCreaDate: Date(), itemUpdDate: Date(), itemTags: [], linkedItemsUID: [])])
    
    var urlFile: URL
    
    init() { LoadData() }
    
    func LoadData() {
        
        func getDocumentsDirectory() -> URL {
            let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
            return paths[0]
        }

        let urlFile = getDocumentsDirectory().appendingPathComponent("/SMT.json")
        
        do {
            let data = try Data(contentsOf: urlFile)
            let decoder = JSONDecoder()
            TTDItemMainList = try decoder.decode(TTDItemList.self, from: data)
        } catch {
            debugPrint(error.localizedDescription)
        }
        
    }
    
    func saveData() {
        let encoder = JSONEncoder()
        do {
            let data = try encoder.encode(TTDItemMainList)
            try data.write(to: urlFile)
        } catch {
            debugPrint(error.localizedDescription)
        }
    }
    
}

I do not understand how restructure the code to avois this issue.

CodePudding user response:

You don't set urlFile during your init. In fact, you never set it (later, your let urlFile = is locally scoped).

The easiest solution looks like turning urlFile into a computed property:

class DataManager: ObservableObject {
        
    static let shared = DataManager()
    
    var TTDItemMainList: TTDItemList = TTDItemList(itemList: [TTDItem(id: UUID(), itemDesc: "", itemCreaDate: Date(), itemUpdDate: Date(), itemTags: [], linkedItemsUID: [])])
    
    var urlFile: URL { //<-- Here
        getDocumentsDirectory().appendingPathComponent("/SMT.json")
    }
    
    init() { loadData() }
    
    func getDocumentsDirectory() -> URL {
        let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
        return paths[0]
    }
    
    func loadData() {
        do {
            let data = try Data(contentsOf: urlFile)
            let decoder = JSONDecoder()
            TTDItemMainList = try decoder.decode(TTDItemList.self, from: data)
        } catch {
            debugPrint(error.localizedDescription)
        }
        
    }
    
    func saveData() {
        let encoder = JSONEncoder()
        do {
            let data = try encoder.encode(TTDItemMainList)
            try data.write(to: urlFile)
        } catch {
            debugPrint(error.localizedDescription)
        }
    }
}
  • Related