Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Delete duplicated object in core data (swift)

Tags:

ios

swift

I'm saving objects to core data from a JSON, which I get using a for loop (let's say I called this setup function. Because the user might stop this loop, the objects saved in core data will be partial. The user can restart this setup function, restarting the parsing and the procedure to save object to core data.

Now, I'm getting duplicated objects in core data if I restart the setup(). The object has an attribute which is id.

I've thought I could fetch first objects that could eventually already exist in core data, save them to an array (a custom type one), and test for each new object to add to core data if already exist one with the same id. The code used is the following:

if !existingCards.isEmpty {
    for existingCard in existingCards {
        if id == existingCard.id {
           moc.deleteObject(existingCard)
           println("DELETED \(existingCard.name)")
        }
    }
}

...
// "existingCards is the array of object fetched previously.
// Code to save the object to core data.

Actually, the app return

EXC_BAD_ACCESS(code=1, address Ox0)

Is there an easier way to achieve my purpose or what should I fix to make my code work? I'm quite new to swift and I can't figure other solution. The main purpose is to delete duplicated core data, BTW.

like image 433
QUB3X Avatar asked May 19 '15 19:05

QUB3X


2 Answers

Swift 4 code to delete duplicate object:

let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Card")
var resultsArr:[Card] = []
do {
    resultsArr = try (mainManagedObjectContext!.fetch(fetchRequest) as! [Card])
} catch {
    let fetchError = error as NSError
    print(fetchError)
}
        
if resultsArr.count > 0 {
    for x in resultsArr {
        if x.id == id {
            print("already exist")
            mainManagedObjectContext.deleteObject(x)
        }
    }
}
like image 128
Lion Avatar answered Oct 31 '22 15:10

Lion


At the end, I managed to make it work.

I had to rewrite my code, because I realized moc.deleteObject() works with a fetch before, which in my previous code wasn't in the same function, but it was in viewDidLoad().

// DO: - Fetch existing cards
var error: NSError?
var fetchRequest = NSFetchRequest(entityName: "Card")
if let results = moc.executeFetchRequest(fetchRequest, error: &error) as? [Card] {

   if !results.isEmpty {
     for x in results {
        if x.id == id {
          println("already exist")
          moc.deleteObject(x)
        }
     }
   }
} else {
   println(error)
}

No more existingCards, the result of the the fetch is now processed as soon as possible. Something isn't clear to me yet, but now my code works. If you have any improvements/better ways, they're welcome.

P.S.: I actually found Apple reference useful but hard to understand because I don't know Obj-C. Often I can figure what the code do, but in swift functions and properties are a bit different.

like image 25
QUB3X Avatar answered Oct 31 '22 14:10

QUB3X