很多时候我们把数据备份导出为json,需要恢复数据需要导入json,那么如何导入json数据以达到恢复数据的目的呢,我们来看看代码 实践:
import UIKit
import CoreData
class ViewController: UIViewController {
lazy var persistentContainer: NSPersistentContainer = {
let container = NSPersistentContainer(name: "你的模型名字")
// 设置 CloudKit 选项
if let description = container.persistentStoreDescriptions.first {
description.setOption(true as NSNumber, forKey: NSPersistentHistoryTrackingKey)
description.setOption(true as NSNumber, forKey: NSInferMappingModelAutomaticallyOption)
description.setOption(true as NSNumber, forKey: NSMigratePersistentStoresAutomaticallyOption)
let options = NSPersistentCloudKitContainerOptions(containerIdentifier: "iCloud.your.bundle.identifier")
options.databaseScope = .private
description.cloudKitContainerOptions = options
}
container.loadPersistentStores { (storeDescription, error) in
if let error = error as NSError? {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
}
return container
}()
@IBAction func importDataButtonTapped(_ sender: UIButton) {
importDataFromJSONFile() //调用导入
}
func importDataFromJSONFile() {
// 获取文档目录
let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
let fileURL = documentsDirectory.appendingPathComponent("要导入的json数据.json")
// 读取 JSON 文件内容
do {
let data = try Data(contentsOf: fileURL)
importDataToCoreData(jsonData: data, context: persistentContainer.viewContext)
} catch {
print("Failed to read JSON file: \(error)")
}
}
func importDataToCoreData(jsonData: Data, context: NSManagedObjectContext) {
do {
if let jsonArray = try JSONSerialization.jsonObject(with: jsonData, options: []) as? [[String: Any]] {
for item in jsonArray {
// 检查是否已经存在相同的记录
if !isItemAlreadyExists(item: item, context: context) {
// 创建新的 CloudItem 对象
let newNote = CloudItem(context: context)
// 设置属性
newNote.noteColor = item["noteColor"] as? String
newNote.noteContent = item["noteContent"] as? String
newNote.noteDate = item["noteDate"] as? String
if let timestamp = item["timestamp"] as? Double {
newNote.timestamp = Date(timeIntervalSince1970: timestamp)
}
}
}
// 保存上下文
do {
try context.save()//同步到云端
print("Data imported and saved successfully.")
} catch {
let nsError = error as NSError
print("Failed to save data: \(nsError), \(nsError.userInfo)")
}
}
} catch {
print("Failed to parse JSON: \(error)")
}
}
func isItemAlreadyExists(item: [String: Any], context: NSManagedObjectContext) -> Bool {
let fetchRequest: NSFetchRequest<CloudItem> = CloudItem.fetchRequest()
// 假设 noteContent 和 noteDate 是唯一的标识符
if let noteContent = item["noteContent"] as? String, let noteDate = item["noteDate"] as? String {
fetchRequest.predicate = NSPredicate(format: "noteContent == %@ AND noteDate == %@", noteContent, noteDate)
}
do {
let results = try context.fetch(fetchRequest)
return !results.isEmpty
} catch {
print("Failed to fetch existing items: \(error)")
return false
}
}
}
详细步骤说明
获取文档目录:
let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
let fileURL = documentsDirectory.appendingPathComponent("notes.json")
读取 JSON 文件内容:
do {
let data = try Data(contentsOf: fileURL)
importDataToCoreData(jsonData: data, context: persistentContainer.viewContext)
} catch {
print("Failed to read JSON file: \(error)")
}
解析 JSON 数据并保存到 Core Data:
在导入每个项目之前,调用 isItemAlreadyExists 方法检查该记录是否已经存在。
如果不存在,则创建新的 CloudItem 对象并设置其属性。
检查记录是否已存在:
使用 NSFetchRequest 和 NSPredicate 来查询现有的记录。
假设 noteContent 和 noteDate 是唯一的标识符,根据这两个字段查询现有的记录。
如果查询结果不为空,则表示记录已经存在。
确保 Core Data 与 CloudKit 集成:
确保你在 persistentContainer 中设置了 CloudKit 选项,如上面的代码所示。
总结
通过以上步骤,我们可以完成json数据导入,并同步到云端,关键点是在导入 JSON 数据时检查并避免重复导入已经存在的记录。另外需要传入context。