如何在 swift 的特定文件路径中读写 from/to 一个 JSON 文件?

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

我正在尝试从 JSON 文件中实现数据管理器单例 class reading/write,但出现此错误:

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

这是代码:

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

我不明白如何重组代码来避免这个问题。

您在 init 期间没有设置 urlFile。事实上,你从来没有设置它(后来,你的 let urlFile = 是局部范围的)。

最简单的解决方案看起来像将 urlFile 变成计算的 属性:

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