Swift Saving Deleted Rows To Core Data - swift

Bit of a beginner here so probably shouldn't be trying core data stuff but anyway, I would like to be able to delete a row by swiping. I have done this but it doesn't save the deleted cells and they come back again. I am using a xcdatamodeld file. If anyone can tell me how to save the deleted files to core data that would be great!
Here is my saving data code:
inputAlert.addAction(UIAlertAction(title: "Save", style: .default, handler: { (action:UIAlertAction) in
let taskTextField = inputAlert.textFields?.first
let descTextField = inputAlert.textFields?.last
if taskTextField?.text != "" && descTextField?.text != "" {
taskItem.task = taskTextField?.text
taskItem.desc = descTextField?.text
do {
try self.managedObjectContext.save()
self.loadData()
}catch {
print("Could not save data \(error.localizedDescription)")
}
}
Here is the code I have so far for the deleting:
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == UITableViewCellEditingStyle.delete {
tasks.remove(at: indexPath.row)
tableView.reloadData()
}
}

Don't let the fact that you are a beginner keep you from using this powerful persistent store friend. CoreData is a big topic, books have been written on it, but it is something that works very well once you understand the core concepts of programming with it. It looks like you want to remove data that is populated in a UITableView and then save what you deleted into CoreData. Let's break down the steps and give you some examples to work with in your own project.
1) Remove data from your UITableView's datasource
2) Save NSManagedObject to CoreData
3) Delete row from UITableView
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == UITableViewCellEditingStyle.delete {
// 1)
let task = tasks.remove(at: indexPath.row)
// 2)
saveToCoreData(task: task)
// 3)
tableView.beginUpdates()
tableView.deleteRows(at: [indexPath], with: .fade)
tableView.endUpdates()
}
}
// Assuming your task is of type "`Task`". You should put whatever data type your task object actually is.
func saveToCoreData(task: Task) {
// Insert Into CoreData (very important)
let managedObject = NSEntityDescription.insertNewObject(forEntityName: "RemovedTask", into: self.context)
// assign values
managedObject.value = task.value
// Save CoreData Context (also, very important)
do {
self.context.save()
}
catch {
print("Could not save CoreData!")
}
}

Related

Swift and Realm Error with Object Management [duplicate]

Im getting this error "Can only delete an object from the Realm it belongs to" every time I try to delete an object from realm on my tableview. Here is the relevant code:
let realm = try! Realm()
var checklists = [ChecklistDataModel]()
override func viewWillAppear(_ animated: Bool) {
checklists = []
let getChecklists = realm.objects(ChecklistDataModel.self)
for item in getChecklists{
let newChecklist = ChecklistDataModel()
newChecklist.name = item.name
newChecklist.note = item.note
checklists.append(newChecklist)
}
tableView.reloadData()
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return checklists.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "ChecklistCell", for: indexPath) as! ListsTableViewCell
cell.name.text = checklists[indexPath.row].name
return cell
}
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
// Delete the row from the data source
try! realm.write {
realm.delete(checklists[indexPath.row])
}
//delete locally
checklists.remove(at: indexPath.row)
self.tableView.deleteRows(at: [indexPath], with: .fade)
}
}
I know it is this part to be specific:
// Delete the row from the data source
try! realm.write {
realm.delete(checklists[indexPath.row])
}
Any ideas of what is going on?
Thanks in advance!
You are trying to delete copies of your Realm objects stored in a collection instead of your actual Realm objects stored in Realm.
try! realm.write {
realm.delete(Realm.objects(ChecklistDataModel.self).filter("name=%#",checklists[indexPath.row].name))
}
Without the definition of CheklistDataModel, I am not sure if I got the NSPredicate right, but you should be able to figure it out from here.
From the code snippets you shared, you appear to be creating new ChecklistDataModel objects but never adding them to any Realm. Then you attempt to delete these objects from your Realm in your try! realm.write block.
Simply instantiating an object does not mean it has been added to a Realm; until it is added to a Realm through a successful write transaction it behaves just like any other Swift instance. Only after you've added the object to a Realm can you successfully delete it from that same Realm.

How to delete a tableview index.row from data core swift 4

I have created an entity called Medications and the function for adding new data is :
#objc func saveUserSettings() {
SVProgressHUD.show()
let name = medicationNameTextField.text
let dosage = dosageTextField.text
let frequency = medicationNameTextField.text
let reminder = dosageTextField.text
let medication = Medications(context: PersistenceService.context)
medication.name = name
medication.dosage = dosage
medication.frequency = frequency
medication.reminder = reminder
PersistenceService.saveContext()
self.meds.append(medication)
}
How can I delete one of those indexes when pressing the delete button at the table view cell?
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
meds.remove(at: indexPath.row)
let task = meds[indexPath.row]
PersistenceService.saveContext()
self.tableView.reloadData()
}
}
Any ideas?
Deleteing from the array here
meds.remove(at: indexPath.row)
doesn't automatically remove it from coreData , you need to use
context.delete(object)
before saving the context see here Swift 3 Core Data Delete Object
Also do it in correct order
let task = meds[indexPath.row]
context.delete(task) // access context anywhere but this statement should run
PersistenceService.saveContext()
meds.remove(at: indexPath.row)

Can't delete cells from UITableView, just the data from said cells

I am making an app that stores events and their data, and it was working flawlessly until I tried to add Core Data, since then, I've been having issues with it. One is the fact that using the delete func doesn't really delete the tablecell, just the data inside. If I try to delete the blank cell, it does nothing. Below is the code for the delete function I am using.
Also, my app for some reason starts with one of these blank cell, which can't be deleted.
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
PersistenceService.context.delete(events[indexPath.row])
do {
try PersistenceService.context.save()
eventLog.reloadData()
} catch let error as NSError {
print("Could not save. \(error), \(error.userInfo)")
}
}
}
You have to remove the item from the context and from the data source array and it's highly recommended to use deleteRows rather than reloading the entire table view to take advantage of the animation
PersistenceService.context.delete(events[indexPath.row])
events.remove(at: indexPath.row)
eventLog.deleteRows(at: [indexPath], with: .fade)
... save context

How to delete specific coreData object from TableView

So I'm trying to delete data from a tableView, which It will delete the cell at the row, but it won't delete the information from coreData, causing it to load again when I call a .reloadData(). I'm really new to coredata and I don't know how to select a specific Recipe item that I make.
Here's where I handle the delete:
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if (editingStyle == UITableViewCellEditingStyle.delete) {
// handle delete (by removing the data from your array and updating the tableview)
recipes.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: UITableViewRowAnimation.automatic)
}
}
Here's how I am creating the items in coreData, if this helps. Also, I have a Git repository here if anyone's willing to look that deep
#IBAction func createNewRecipeButton(_ sender: Any) {
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
let newRecipe = Recipe(context: context)
newRecipe.title = recipeTitleTextBox.text
newRecipe.instructions = recipeInstructionsTextBox.text
newRecipe.time = recipeTimeTextBox.text
(UIApplication.shared.delegate as! AppDelegate).saveContext()
navigationController!.popToRootViewController(animated: true)
}
Your current removal method merely deletes the recipe from the storage array. You need to tell the context to get rid of it as well…
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if (editingStyle == UITableViewCellEditingStyle.delete) {
let recipe = recipes.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: UITableViewRowAnimation.automatic)
guard let moc = recipe.managedObjectContext else { return }
moc.delete(recipe)
moc.processPendingChanges()
}
}
You might also want to look into using a NSFetchedResultsController. There are several tutorials around.

removing from firebase database

I am creating a online ordering service for practice project. Two things I've read into recently is the editing tableview function. when I go to swipe to delete a item it won't take the right item out of the database. Also, if there is only one item in the array and I try to delete it it will make it crash. Anyone have any idea whats going on with this?
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
orderNumber.remove(at: indexPath.row)
itemsArray.remove(at: indexPath.row)
priceArray.remove(at: indexPath.row)
quantityArray.remove(at: indexPath.row)
databaseRef.child("Users/\((authRef.currentUser?.uid)!)/Order/\(orderNumber.remove(at: indexPath.row))").removeValue { (error, ref) in
if error != nil {
print(error?.localizedDescription as Any)
} else {
}
}
}
Looks like you just need to check the array count before deleting it:-
if orderNumber.count > indexPath.row {
orderNumber.remove(at: indexPath.row)
}
if itemsArray.count > indexPath.row {
itemsArray.remove(at: indexPath.row)
}
if priceArray.count > indexPath.row {
priceArray.remove(at: indexPath.row)
}
if quantityArray.count > indexPath.row {
quantityArray.remove(at: indexPath.row)
}
Apparently, you're removing from orderNumber twice. First you're removing here:
orderNumber.remove(at: indexPath.row)
Then you're removing here:
child("Users/\((authRef.currentUser?.uid)!)/Order/\(orderNumber.remove(at: indexPath.row))")
Any specific reason you're using multiple collections?