Cannot Delete Text from Core Data - ios

I have a problem. I try to delete items from an array but after deletion when I rebuild the project I still saw my deleted items on screen.
Here is my code.
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else {
return
}
let managedContext = appDelegate.persistentContainer.viewContext
let entity = NSEntityDescription.entity(forEntityName: "PasswordModel", in: managedContext)!
let item = NSManagedObject(entity: entity, insertInto: managedContext)
if editingStyle == .delete {
self.passwordList.remove(at: indexPath.row)
self.tableView.beginUpdates()
self.tableView.deleteRows(at: [indexPath], with: .automatic)
self.tableView.endUpdates()
managedContext.delete(item)
do {
try managedContext.save()
}catch let saveErr {
print("Failed to delete password", saveErr)
}
}
}
How can I save this deletion to my Core Data?
Thanks.

Related

Tableview cells not showing up correctly, and core data not loading the saved data correctly

in my app I am trying to create a budgeting app. I have tried creating a custom tableView Cell, but when it is run in the simulator, the tableView is condensed and does not show up correctly. As well as this, I am trying to save and load data from Coredata. However when the viewController loads, the error "Fatal Error: Index Out of Range" appears. I have viewed many coreData tutorials and threads however none of them help with my issue.
I want my tableViews to show up like this: storyboard view
However they appear like this.
Here is my code for the tableView and core data.
Any help is appreciated, thank you!
ViewController
var goals: [NSManagedObject] = []
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return CGFloat(goals.count)
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! AllGoalsTableViewCell
let goal = goals[1]
cell.titleLabel?.text = goal.value(forKey: "title") as? String
return cell
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
//1
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else {
return
}
let managedContext = appDelegate.persistentContainer.viewContext
//2
let fetchRequest = NSFetchRequest<NSManagedObject>(entityName: "Goal")
//3
do {
goals = try managedContext.fetch(fetchRequest)
} catch let error as NSError {
print("Could not fetch. \(error), \(error.userInfo)")
}
if !self.goals.isEmpty
{
tableView.reloadData()
}
}
addNewViewController
var goals: [NSManagedObject] = []
func save(title: String, goalAmount: Double, percent: Double, amountPerWeek: Double) {
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else {
return
}
//1
let managedContext = appDelegate.persistentContainer.viewContext
//2
let entity = NSEntityDescription.entity(forEntityName: "Goal", in: managedContext)!
let goal = NSManagedObject(entity: entity, insertInto: managedContext)
//3
goal.setValue(title, forKey: "title")
goal.setValue(goalAmount, forKey: "goalAmount")
goal.setValue(percent, forKey: "percent")
goal.setValue(amountPerWeek, forKey: "amountPerWeek")
//4
do {
try managedContext.save()
goals.append(goal)
} catch let error as NSError {
print("Could not save. \(error), \(error.userInfo)")
}
}
#IBAction func addNewAction(_ sender: Any)
//CoreData
self.save(title: title, goalAmount: goalAmount ?? 0.0, percent: percent, amountPerWeek: amountPerWeekFloat ?? 0.0)
print("saved")
}

Error in CoreData when trying to save an array. 'Cannot convert value of type 'String' to expected argument type 'NSManagedObject''

I am using CoreData to save a tableView to the device. I am relatively new to CoreData, and cannot figure this out. I get the error:
'Cannot convert value of type 'String' to expected argument type 'NSManagedObject''
On the line:
favourites.append(addNewMemory.text!)
//MARK:- Core Data
func save(name: String) {
guard let appDelegate =
UIApplication.shared.delegate as? AppDelegate else {
return
}
// 1
let managedContext =
appDelegate.persistentContainer.viewContext
// 2
let entity =
NSEntityDescription.entity(forEntityName: "Memory",
in: managedContext)!
let person = NSManagedObject(entity: entity,
insertInto: managedContext)
// 3
person.setValue(name, forKeyPath: "name")
// 4
do {
try managedContext.save()
favourites.append(person)
} catch let error as NSError {
print("Could not save. \(error), \(error.userInfo)")
}
}
var favourites: [NSManagedObject] = []
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return favourites.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: UITableViewCell.CellStyle.default, reuseIdentifier: "Cell")
/*cell.imageView?.image = UIImage(named: "applelogo")
cell.imageView?.setRounded()
cell.imageView?.clipsToBounds = true
*/
let favMemory = favourites[indexPath.row]
cell.textLabel?.text = favMemory.value(forKeyPath: "name") as? String
return cell
}
#IBAction func addButtonTapped(_ sender: UIButton) {
insertNewCell()
}
func insertNewCell() {
favourites.append(addNewMemory.text!)
let indexPath = IndexPath(row: favourites.count - 1, section: 0)
tableView.beginUpdates()
tableView.insertRows(at: [indexPath], with: .automatic)
tableView.endUpdates()
addNewMemory.text = ""
view.endEditing(true)
}
I expected the app to save the string, but it does not work. How can I fix this?
You are mixing up the text property of the text field and the Core Data entity. Obviously favourites is declared as [NSManagedObject] so you can't append a string. That's what the error message is telling you.
You have to insert a new record in insertNewCell. The easiest solution is to call save and return a Bool from save to indicate that the insertion was successful.
And you are encouraged to use more contemporary API. If there is no Memory subclass create one
var favourites = [Memory]()
...
func save(name: String) -> Bool {
let appDelegate = UIApplication.shared.delegate as! AppDelegate // force unwrapping is perfectly fine
// 1
let managedContext = appDelegate.persistentContainer.viewContext
// 2
let person = Memory(context: managedContext)
// 3
person.name = name
// 4
do {
try managedContext.save()
favourites.append(person)
return true
} catch let error as NSError {
print("Could not save. \(error), \(error.userInfo)")
return false
}
}
and change insertNewCell to
func insertNewCell() {
guard save(name: addNewMemory.text!) else { return }
let indexPath = IndexPath(row: favourites.count - 1, section: 0)
tableView.insertRows(at: [indexPath], with: .automatic)
addNewMemory.text = ""
view.endEditing(true)
}
beginUpdates/endUpdates is pointless.

Get error "Object has been deleted or invalidated" when delete Item in realm

i load tableview data from realm
let tasks = realmManager.objects(ModelTask.self).filter("planId == %#", currentPlan.id)
datasource = Array(tasks)
tableViewMain.reloadData()
and delete a item when user click delete in tableview
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
let delete = UITableViewRowAction(style: .normal, title: "删除".localized) {
[weak self] action, index in
guard let `self` = self else {return}
let task = self.datasource[indexPath.row]
let realm = try! Realm()
try? realm.write {
realm.delete(task)
}
self.datasource.remove(at: indexPath.row)
tableView.reloadData()
}
delete.backgroundColor = UIColor(hex:"fe5d5c")
return [delete]
}
and it crashed when realm delete this item.
i got error message reason: 'Object has been deleted or invalidated.'
i'm confused this works fine at other view controller.
why not work here?
Edit ----------
solved this problem .
because after i delete this item , i have a log function that used this item.
that's why it always crash.
thank u everyone
try this
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
let delete = UITableViewRowAction(style: .normal, title: "删除".localized) {
[weak self] action, index in
guard let `self` = self else {return}
let task = self.datasource[indexPath.row]
let realm = try! Realm()
try? realm.write {
realm.delete(task)
self.datasource = realmManager.objects(ModelTask.self).filter("planId == %#", currentPlan.id)
}
tableView.reloadData()
}
delete.backgroundColor = UIColor(hex:"fe5d5c")
return [delete]
}
Or you can check isInvalidated before you remove it from data source
if !task.isInvalidated{
self. datasource.removeObject(task)
}

how to delete row from coredata (Entity) ios swift

i am new to CORE DATA in my app i am using coredata.
i just stored data in my core data. my entity name is "FEED" and i have a rows with name "title", "id " , "link" ,"desc" so now i want to delete perticular row on based on "id". so how can i do this?
Here is my code,
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell : MessageMusicCell = tableView.dequeueReusableCellWithIdentifier("MessageMusicCell") as! MessageMusicCell
cell.pinButton.tag = indexPath.row
cell.pinButton.addTarget(self, action: #selector(MessageViewController.buttonDeletePressed(_:)), forControlEvents: UIControlEvents.TouchUpInside)
cell.selectionStyle = .None
person = people[indexPath.row]
cell.lbl_title_msg_music.text = person!.valueForKey("title") as? String
cell.img_message_music.image = UIImage(named: "PlaceHolder")
cell.desc_msg_music.text = person!.valueForKey("desc") as? String
return cell
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
print(people.count)
return people.count
}
func buttonDeletePressed(sender:UIButton) {
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let cell : MessageMusicCell = tableView.dequeueReusableCellWithIdentifier("MessageMusicCell") as! MessageMusicCell
}
so how can i do this?
Try Like this,
func buttonDeletePressed(sender:UIButton) {
let appDel:AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let context:NSManagedObjectContext = appDel.managedObjectContext
let index = sender.tag
context.deleteObject(people[index] as NSManagedObject)
people.removeAtIndex(index)
let _ : NSError! = nil
do {
try context.save()
self.tableView.reloadData()
} catch {
print("error : \(error)")
}
}
Hope this will help you.
func deleteFeed(id:String)
{
let appDelegate =
UIApplication.sharedApplication().delegate as? AppDelegate
let managedContext = appDelegate?.managedObjectContext
let fetchRequest = NSFetchRequest(entityName:"FEED")
fetchRequest.predicate = NSPredicate(format: "id = %#", "\(id)")
do
{
let fetchedResults = try managedContext!.executeFetchRequest(fetchRequest) as? [NSManagedObject]
for entity in fetchedResults! {
managedContext?.deleteObject(entity)
}
}
catch _ {
print("Could not delete")
}
}
Now you can call this function and pass the id whatever you want to delete
func buttonDeletePressed(sender:UIButton){
deleteFeed("1")
}
You can delete data like,
let appDel:AppDelegate = UIApplication.sharedApplication().delegate as AppDelegate
let context:NSManagedObjectContext = appDel.managedObjectContext!
context.deleteObject(myData[indexPath.row] as NSManagedObject)
myData.removeAtIndex(indexPath.row)
context.save(nil)
this is done from commitEditingStyle so here used indexPath.row. You can pass your id if you want to delete data from other place. If you want to delete data from tableview then you should implement commitEditingStyle and delete data like mentioned above.
Hope this will help :)
override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
switch editingStyle {
case .Delete:
// remove the deleted item from the model
let appDel: AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let context: NSManagedObjectContext = appDel.managedObjectContext
context.deleteObject(people[indexPath.row] )
people.removeAtIndex(indexPath.row)
do {
try context.save()
} catch _ {
}
// remove the deleted item from the `UITableView`
self.tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
default:
return
}
}
Hope this could be of some help!

remove string from coredata swift

i am trying to remove one string from coredata and i created this func:
override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if (editingStyle == UITableViewCellEditingStyle.Delete) {
self.statusArray.removeAtIndex(indexPath.row)
self.tableView.reloadData()
// Rimuovo da CoreData
var appDel = UIApplication.sharedApplication().delegate as! AppDelegate
var context : NSManagedObjectContext! = appDel.managedObjectContext!
tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
let request = NSFetchRequest(entityName: "Status")
request.returnsObjectsAsFaults = false
let result:NSArray = context.executeFetchRequest(request, error: nil)!
context.deleteObject(result[indexPath.row] as! Status)
context.save(nil)
}
}
but actually this one give me the SIGABRT error when i try to delete something from the tableView! What is wrong with this function?
Try the following example for deleting.It might be helpful.
var request = NSFetchRequest(entityName: "Status")
var new_sync_details = NSEntityDescription.insertNewObjectForEntityForName("Status", inManagedObjectContext: context) as! NSManagedObject
var err: NSErrorPointer?
if var results = context.executeFetchRequest(request, error: nil) as? [Status] {
println("\nResults count: \(results.count)")
for param in results{
println("\nResults param: \(param)")
new_sync_details.managedObjectContext!.deleteObject(param as NSManagedObject)
}
}

Resources