Delete rows from UITableView and update array from NSUserDefaults - swift

With the tableview I am trying to delete only one record of the list but with my code it deletes all the userDefault data. how do i delete only one record?
cell.buttonPressed = {
self.recDictionaryId?["\(title)"] = "\(sentence)"
self.pokemonArray.remove(at: indexPath.row)
self.tvPokemon.deleteRows(at: [indexPath], with: .automatic)
let defaults = UserDefaults.standard
defaults.set(self.pokemonArray, forKey: "UserDefSaveDictionary")
defaults.synchronize()
self.tvPokemon.reloadData()
}
I also tried with:
removeObject(forKey: "UserDefSaveDictionary")
but the result is the same

override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
objects.remove(at: indexPath.row)
self. deleteItem(indexPath.row)
tableView.deleteRows(at: [indexPath], with: .fade)
}
}
func deleteItem(_ index: Int) {
let userDefaults = UserDefaults.standard
if let data = userDefaults.data(forKey:”keyName”) , var array = try? JSONDecoder().decode([Model].self, from: data) {
array.remove(at: index)
guard let result = try? JSONEncoder().encode(array) else { return }
userDefaults.set(result, forKey:”keyName”)
}
}
you have to fetch the UserDefaults response array and convert it to a model then it would be much easier, if you want make this better you can try by adding a completion block to deleteItem() function and inside that you can perform real deletion

Related

swipe delete reappears item in favorite tab

So I'm trying to implement a swipe delete of my favorite items off the favorites tab. The swipe implementation works but when I go back to the Favorites Tab, the item deleted reappears. I'm using core data and I know it is not deleting it from core data but not sure how to fix it. This is my file for the favorites tab:
import UIKit
import CoreData
class FavAnimeViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
#IBOutlet var tableView: UITableView!
var favorites = [NSManagedObject]()
var numAnime = 0
var managedObjectContext: NSManagedObjectContext!
override func viewDidLoad() {
super.viewDidLoad()
tableView.dataSource = self
tableView.delegate = self
// Do any additional setup after loading the view.
}
//loads every time view appears
override func viewDidAppear(_ animated: Bool) {
load()
}
func load() {
//1
guard let appDelegate =
UIApplication.shared.delegate as? AppDelegate else {
return
}
let managedContext =
appDelegate.persistentContainer.viewContext
//2
let fetchRequest =
NSFetchRequest<NSManagedObject>(entityName: "Favorite")
//3
do {
favorites = try managedContext.fetch(fetchRequest)
tableView.reloadData()
} catch let error as NSError {
print("Could not fetch. \(error), \(error.userInfo)")
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return favorites.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "FavTableViewCell") as! FavTableViewCell
let favAnime = favorites[indexPath.row]
cell.favtitleLabel.text = favAnime.value(forKeyPath: "title") as? String
cell.favsumLabel.text = favAnime.value(forKeyPath: "synopsis") as? String
if let poster = favAnime.value(forKey: "poster") as? String{
let posterUrl = URL(string: poster)!
cell.favposterView.af.setImage(withURL: posterUrl)
}
return cell
}
//MARK: Delete favorite items
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
favorites.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: .fade)
} else if editingStyle == .insert {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view.
}
}
}
if any can help that be great
The changes (in this case Delete) wont be seen affected until you save the state of the NSManagedObjectContext, Helpfully, managed object context has a matching delete() method that will delete any object regardless of its type or location in the object graph. Once an object has been deleted from the context, we can then call saveContext() to write that change back to the persistent store so that the change is permanent.
do {
try managedObjectContext.save()
} catch (let error) {
print(error.localizedDescription)
}
Remember: you must call saveContext() whenever you want your changes to persist.
I Hope I Helped!
Core Data | nsmanagedobjectcontext
Delete from CoreData
func deleteParticularRecord(id:String){
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
// use predicate for delete particular record from coredata.
let fetchRequest:NSFetchRequest<NSFetchRequestResult> = NSFetchRequest.init(entityName: "EnitityName")
let predicate = NSPredicate(format: "id = '\(id)'")
fetchRequest.predicate = predicate
let objects = try! context.fetch(fetchRequest)
for obj in objects {
context.delete(obj as! NSManagedObject)
}
do {
try context.save() // <- remember to put this :)
} catch {
// Do something... fatalerror
}
}
// Call
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
favorites.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: .fade)
// use id or object id
deleteParticularRecord(id: "_Id_")
} else if editingStyle == .insert {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view.
}
}
// Hope its works :)

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)

Deleting String from CoreData

I'm having problems deleting an item from my Core Data, and having looked at lots of other examples and questions - they all say about deleting an NSManagedObject whereas I'm trying to delete the item at the indexPath.row (which is a String).
var itemsArray = [String]()
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
What would I put in the following function?
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if (editingStyle == .delete) {
}
}
Loading items in Core Data
func loadItems() {
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Items")
request.returnsObjectsAsFaults = false
do {
let results = try context.fetch(request)
if results.count > 0 {
for result in results as! [NSManagedObject] {
if let product = result.value(forKey: "product") as? String {
self.itemsArray.append(product)
}
}
}
} catch {
print("Error")
}
}
To be able to delete the object you have to use the NSManagedObject as data source
var itemsArray = [Items]()
The loadItems can be reduced to
func loadItems() throws {
let request = NSFetchRequest<Items>(entityName: "Items")
request.returnsObjectsAsFaults = false
itemsArray = try context.fetch(request)
}
Put the do - catch block around the loadItems() call and print the error instance, not a meaningless literal string.
In cellForRow use
let item = itemArray[indexPath.row]
let product = item.product
To delete the item you have to remove it from the data source, then delete the item in the context and then save the context:
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
let objectToDelete = itemArray[indexPath.row]
itemArray.remove(at: indexPath.row)
context.delete(objectToDelete)
// here add code to save the context
self.tableView.deleteRows(at: [indexPath], with: .fade) // and you have to update the table view
}
}

How to remove a specific key from Firebase in Swift 3

How can I get the marked key then remove it from UITableView swift 3 ?
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
self.grocery.remove(at: indexPath.row)
self.tableView.deleteRows(at: [indexPath], with: .automatic)
}
}
To remove you can simply set the value as nil to remove it from firebase. After you've called the remove function then make sure to remove the row from the tableView.
func removeObjectFromFireBase(userKey: String, removeThisGrocery: String) {
let ref = Database.database().reference()
let groceryRef = ref.child("Users").child(userKey).child("Grocery")
groceryRef.child(removeThisObject).setValue(nil)
}
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
let deleteAction = UITableViewRowAction(style: .destructive, title: "DELETE") { (rowAction, indexPath) in
//Call the removeFromFirebase function with the required parameters
removeObjectFromFirebase(userKey: userKey, removeThisGrocery: groceryKey)
tableView.deleteRows(at: [indexPath], with: .automatic)
}
deleteAction.backgroundColor = UIColor.red
return [deleteAction, addAction]
}
You can remove any data from Firebase as following:
let ref = Database.database().reference()
let groceryRef = ref.child("Users").child(userKey).child("Grocery")
groceryRef.removeValue()

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.