我能够保存和检索数据从核心数据,但我不知道如何不重复或避免在核心数据中保存相同的数据。我复制相同的值,但我不想保存相同的值在核心数据,如果它已经存在。我不知道什么代码检查不复制它,而我保存它?
func fetchDbdata(){
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let managedContext = appDelegate.persistentContainer.viewContext
let fetchRequest = NSFetchRequest<NSManagedObject>(entityName: "Day")
do {
let dayList = try managedContext.fetch(fetchRequest)
for item in dayList{
let id = item.value(forKeyPath: "id") as? String
let name = item.value(forKey: "name") as? String
print(name as Any)
}
}
catch let error as NSError {
print("(error), (error.userInfo)")
}
}
func saveDaysList(id: String,name: String) {
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else {
return
}
let managedContext = appDelegate.persistentContainer.viewContext
let entity = NSEntityDescription.entity(forEntityName: "Day", in: managedContext)!
let days = NSManagedObject(entity: entity, insertInto: managedContext)
days.setValue(id, forKey: "id")
days.setValue(name, forKey: "name")
do {
try managedContext.save()
daysData.append(days)
} catch let error as NSError {
print("Could not save. (error), (error.userInfo)")
}
}
首先,应该创建您的Day
实体的CoreData类。这样控制起来会更方便。
class Day: NSManagedObject {
@NSManaged var id: String
@NSManaged var name: String
}
在Core Data中处理复制问题有一个常见的场景。你应该首先找到相同的项目中。对于我来说,大多数时候,我会首先在缓存中找到项目,如果前面的操作失败,则运行NSFetchRequest
来获取它。
我可以给你一些示例方法。
public protocol Managed: class, NSFetchRequestResult {
static var entity: NSEntityDescription { get }
static var entityName: String { get }
}
extension Managed where Self: NSManagedObject {
public static func materializedObject(in context: NSManagedObjectContext, matching predicate: NSPredicate) -> Self? {
for object in context.registeredObjects where !object.isFault {
guard let result = object as? Self, predicate.evaluate(with: result) else { continue }
return result
}
return nil
}
public static func fetch(in context: NSManagedObjectContext, configurationBlock: (NSFetchRequest<Self>) -> () = { _ in }) -> [Self] {
let request = NSFetchRequest<Self>(entityName: Self.entityName)
configurationBlock(request)
return try! context.fetch(request)
}
public static func findOrFetch(in context: NSManagedObjectContext, matching predicate: NSPredicate) -> Self? {
guard let object = materializedObject(in: context, matching: predicate) else {
return fetch(in: context) { request in
request.predicate = predicate
request.returnsObjectsAsFaults = false
request.fetchLimit = 1
}.first
}
return object
}
}
extension Day: Managed {
}
使用findOrFetch
方法,您可以尝试找到复制项。如果找到了该项,则不应该创建新项。否则,您可以在数据库中插入一个新项。
假设id
是唯一属性,查找代码如下:
let predicate = NSPredicate(format: "id=%@", "your id value")
if let object = Day.findOrFetch(in: context, matching: predicate) {
// update your old item here.
} else {
// insert your new item here.
}