Reputation: 416
I am able to save and retrieve data from Core Data, but I don't know how to not duplicate or avoid the same saved data in Core Data.i am duplicating the same value but i don't want to save the same value in core data if it already exist. I don't know what code to check for not duplicating it while i save it?
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)")
}
}
Upvotes: 1
Views: 1288
Reputation: 179
First and foremost, CoreData class of your Day
entity should be created. It will be more convenient to get it under control.
class Day: NSManagedObject {
@NSManaged var id: String
@NSManaged var name: String
}
Dealing with duplicating problem in Core Data has a common scenario. It is you should first find the same item in the context. For me, most of the time, I will first find the item in caches, and run an NSFetchRequest
to fetch it if the preceding operation failed.
I could give some sample methods to you.
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 {
}
Use the findOrFetch
method you could try finding the duplicating item. If the item was found, then you should not create a new one. Otherwise you could insert a new item to the db.
Assuming id
is the unique property, the finding code will be like below:
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.
}
Upvotes: 1