在 SwiftUI 中将加载的 json 文件中的更改保存到 Core Data
Posted
技术标签:
【中文标题】在 SwiftUI 中将加载的 json 文件中的更改保存到 Core Data【英文标题】:Saving changes from a loaded json File to Core Data in SwiftUI 【发布时间】: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)")
【问题讨论】:
【参考方案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
【讨论】:
谢谢,这很好地解决了我的问题。我现在就试试看。以上是关于在 SwiftUI 中将加载的 json 文件中的更改保存到 Core Data的主要内容,如果未能解决你的问题,请参考以下文章
在 SwiftUI 中将 ObservableObject 链接到 DatePicker
SwiftUI:尝试加载本地 JSON 数据时,Canvas 出现预览错误