【问题标题】:Saving changes from a loaded json File to Core Data in SwiftUI在 SwiftUI 中将加载的 json 文件中的更改保存到 Core Data
【发布时间】:2021-01-01 20:18:33
【问题描述】:

我想用 json 文件加载我的数据。到现在为止还挺好。但现在我很挣扎。如果用户对油对象进行了一些更改并想要保存它们怎么办?我的想法是,我将更改后的油对象保存到 CoreData。但这有什么可能?因为每次用户启动应用程序时,都会加载未修改的 json 文件,并且用户不会看到他更改的对象。我该如何处理?还是我的想法不对?

struct Oil: Codable, Hashable, Identifiable {
    var id: Int
    
    let image: String
    let color: String
    
    let title: String
    let subtitle: String
    let description: String
    
    var localizedTitle: LocalizedStringKey {
        return LocalizedStringKey(title)
    }
    var localizedDescription: LocalizedStringKey {
        return LocalizedStringKey(description)
    }
    
    var isFavorite: Bool
    
    static let exampleOil = Oil(id: 10001, image: "",color: "lavenderColor" ,title: "lavender", subtitle: "Lavandula angustifolia", description: "", isFavorite: false)
    
}

final class Oils: ObservableObject {
    
    var oils: [Oil] = load("oilDatabase.json")
}


func load<T: Decodable>(_ filename: String) -> T {
    let data: Data

    guard let file = Bundle.main.url(forResource: filename, withExtension: nil)
    else {
        fatalError("Couldn't find \(filename) in main bundle.")
    }

    do {
        data = try Data(contentsOf: file)
    } catch {
        fatalError("Couldn't load \(filename) from main bundle:\n\(error)")
    }

    do {
        let decoder = JSONDecoder()
        return try decoder.decode(T.self, from: data)
    } catch {
        fatalError("Couldn't parse \(filename) as \(T.self):\n\(error)")
    }
}

【问题讨论】:

    标签: json swift core-data swiftui


    【解决方案1】:

    你真的需要核心数据吗?如果您只是存储一个 json 文件,您可以节省很多复杂性,只需将文件的更新版本写入文档目录。

    您所要做的就是检查文件是否存在于文档目录中,如果它确实从那里加载它,否则从您的包中加载它。

    这将获取文档目录的 URL

    func getDocumentsDirectory() -> URL {
        let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
        return paths[0]
    }
    

    然后我们只需要更新您的load 以在加载之前检查文件是否存在于文档目录中。

    func load<T: Decodable>(_ filename: String) -> T {
        let data: Data
    
        // Check that the fileExists in the documents directory
        let filemanager = FileManager.default
        let localPath = getDocumentsDirectory().appendingPathComponent(filename)
    
        if filemanager.fileExists(atPath: localPath.path) {
            
            do {
                data = try Data(contentsOf: localPath)
            } catch {
               fatalError("Couldn't load \(filename) from documents directory:\n\(error)")
            }
    
        } else {
            // If the file doesn't exist in the documents directory load it from the bundle
            guard let file = Bundle.main.url(forResource: filename, withExtension: nil)
            else {
                fatalError("Couldn't find \(filename) in main bundle.")
            }
    
            do {
                data = try Data(contentsOf: file)
            } catch {
                fatalError("Couldn't load \(filename) from main bundle:\n\(error)")
            }
        }
    
    
        do {
            let decoder = JSONDecoder()
            return try decoder.decode(T.self, from: data)
        } catch {
            fatalError("Couldn't parse \(filename) as \(T.self):\n\(error)")
        }
    }
    

    您还需要保存对 json 所做的任何更改。您可以使用以下函数来做到这一点。

    func save<T: Encodable>(_ filename: String, item: T) {
    
        let encoder = JSONEncoder()
        do {
            let url = getDocumentsDirectory().appendingPathComponent(filename)
            let encoded = try encoder.encode(item)
            let jsonString = String(data: encoded, encoding: .utf8)
            try jsonString?.write(to: url, atomically: true, encoding: .utf8)
        } catch {
            // handle your error
        }
    }
    
    

    【讨论】:

    • 谢谢,这很好地解决了我的问题。我现在就试试看。
    猜你喜欢
    • 2019-03-04
    • 2020-01-18
    • 1970-01-01
    • 1970-01-01
    • 2012-01-15
    • 1970-01-01
    • 2015-07-24
    • 1970-01-01
    • 2018-07-02
    相关资源
    最近更新 更多