Cole Hastings
Cole Hastings

Reputation: 1

NSManagedObject value gets reset if last UITableViewCell is deleted from CoreData

I have an app that increments my NSManagedObject value, "totalGold", by 5, saves it, and deletes the table view cell from CoreData every time the swipe to delete function for table views is used. My NSManagedObject subclass is:

extension Goal {

@nonobjc public class func fetchRequest() -> NSFetchRequest<Goal> {
    return NSFetchRequest<Goal>(entityName: "Goal");
}

@NSManaged public var created: NSDate?
@NSManaged public var desc: String?
@NSManaged public var title: String?
@NSManaged public var difficulty: String?
@NSManaged public var totalGold: Int64
@NSManaged public var frequency: String?

}

The code for the swipe to delete is:

 func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
    if editingStyle == UITableViewCellEditingStyle.delete{
        let fetchRequest: NSFetchRequest<Goal> = Goal.fetchRequest()

        do {
            let array_users = try context.fetch(fetchRequest)

            let user = array_users[0]

            var count: Int64 = user.totalGold
            count += 5
            user.totalGold = count
            print(user.value(forKey: "totalGold")!)
            let str = String(describing: user.totalGold)
            totalGold.text = str
            ad.saveContext()
             }

            catch {
            print("Error with request: \(error)")
            }

        let managedObject: NSManagedObject = controller.object(at: indexPath) as NSManagedObject;
        context.delete(managedObject)
        ad.saveContext()
    }
}

Then when i want to reload the most recent value for totalGold, in viewDidLoad, I call the attemptFetch2 function to retrieve the latest value for "totalGold" and set it to the UILabel's text, as done in the swipe to delete:

func attemptFetch2(){
let fetchRequest: NSFetchRequest<Goal> = Goal.fetchRequest()

   do {
    let array_users = try context.fetch(fetchRequest)

        let user = array_users[0]
        print(user.value(forKey: "totalGold")!)
        let str = String(describing: user.value(forKey: "totalGold") as! Int64)
        totalGold.text = str

        //save the context
        do {
            try context.save()
            print("saved!")
        } catch let error as NSError  {
            print("Could not save \(error), \(error.userInfo)")
        } catch {
        }
    }
 catch {
    print("Error with request: \(error)")
    }




}

This code works fine, saves the object properly and fetches it properly, unless the tableview becomes empty. When the tableview is empty (or better put: when i delete my last table view cell) , my "totalGold" NSManagedObject value gets reset to its default value 0. So essentially, this code only works unless there is at least one table view cell in my table view at all times, which makes it seem as though "totalGold" is saved only within my given tableView. Is there any way for me to have "totalGold" not reset every time the last table view cell is deleted?

Upvotes: 0

Views: 51

Answers (1)

Jon Rose
Jon Rose

Reputation: 8563

Your model is setup wrong. The property totalGold is a global property unrelated to any individual goal. So it shouldn't be a property of a goal object. It should either be stored in a separate user entity, or in a different store completely (like userDefaults).

Upvotes: 0

Related Questions