Hayden Passmore
Hayden Passmore

Reputation: 1155

Swift code is adding unwanted nil data to core data

I am trying to include reminders and also add to the users calendar into my app. However I am running into a problem, when I try to load the data saved in core data I am getting nil. I am only getting nil data after loading it a few times but it increases each time I reload the app.

addReminderToCalendar function

/*
 *
 *This function adds the reminder to the devices calendar and to the devices local storage
 *
 */
func addReminderToCalendar(newReminder : Reminder){
    print("adding reminder :" + newReminder.reminderName)
    /*print(newReminder.reminderDescription)
     print(newReminder.reminderDate)
     print(newReminder.reminderID)
     print(newReminder.reminderName)*/
    if(newReminder.reminderID != nil && newReminder.reminderDate != nil && newReminder.reminderDescription != nil && newReminder.reminderName != nil){
        //print("Adding Reminder to Calendar")
        let appDelegate = UIApplication.shared.delegate as! AppDelegate!
        let managedContext = appDelegate?.managedObjectContext
        let entity =  NSEntityDescription.entity(forEntityName: "Reminders", in:managedContext!)
        let reminderDB = NSManagedObject(entity: entity!, insertInto: managedContext)
        //  print("Reminder ID :" + String(newReminder.reminderID))
        if(checkForReminder(newReminder) == -1){//Checking that the reminder is not already added
            print("addReminderToCalendar :")
            print(newReminder.reminderID)
            reminderDB.setValue(newReminder.reminderID, forKey: "reminderID")
            reminderDB.setValue(newReminder.reminderName, forKey: "reminderName")
            reminderDB.setValue(newReminder.reminderDescription, forKey: "reminderDescription")
            reminderDB.setValue(newReminder.reminderDate, forKey: "reminderDate")
            reminders.append(newReminder)
        }
        if (managedContext?.hasChanges)! {
            do {
                try managedContext?.save()
            } catch {
                //print(newReminder)
                NSLog("Error Here")
            }
        }
    }else{
        print("The reminder to be added was nil")
    }
}

loadReminder function

    /*
 * This function loads the reminders that have been stored in the device
 */
func loadReminders(){

    let appDelegate = UIApplication.shared.delegate as! AppDelegate

    let managedContext = appDelegate.managedObjectContext

    let fetchRequest:NSFetchRequest<NSFetchRequestResult> = NSFetchRequest(entityName: "Reminders")

    let results = try? managedContext.fetch(fetchRequest)

    storedReminders = results as! [NSManagedObject]
    print(storedReminders.count)
    //print(storedReminders[0].value(forKey: "reminderID"))
    if (storedReminders.count > 0){
        for index in 0 ... storedReminders.count - 1{
            print("Loading reminder with ID : ")
            print(storedReminders[index].value(forKey: "reminderID"))
            print("Loading reminder with Name : ")
            print(storedReminders[index].value(forKey: "reminderName"))

            if(storedReminders[index].value(forKey: "reminderID") != nil && storedReminders[index].value(forKey: "reminderName") != nil && storedReminders[index].value(forKey: "reminderDescription") != nil && storedReminders[index].value(forKey: "reminderDate") != nil){ //checking that the values are not null
                let loadedReminder = Reminder()
                loadedReminder.reminderID = storedReminders[index].value(forKey: "reminderID") as! Double
                loadedReminder.reminderName = storedReminders[index].value(forKey: "reminderName") as! String
                loadedReminder.reminderDescription = storedReminders[index].value(forKey: "reminderDescription") as! String
                loadedReminder.reminderDate = (storedReminders[index].value(forKey: "reminderDate") as! NSDate) as Date!
                reminders.append(loadedReminder)
            }
        }
    }
}

reminder Class

import Foundation
import UIKit
import CoreData

class Reminder :UICollectionViewCell{

   var reminderDate: Date!
   var reminderDescription: String!
   var reminderID: Double!
   var reminderName: String!

}

EDIT I have added to my load reminders the following lines, This is to stop the core data being filled with nil values. }else{ //delete this reminder managedContext.delete(storedReminders[index] as NSManagedObject) print("deleted data") } So my loadReminders function now looks like this

/* * This function loads the reminders that have been stored in the device */ func loadReminders(){

let appDelegate = UIApplication.shared.delegate as! AppDelegate

let managedContext = appDelegate.managedObjectContext

let fetchRequest:NSFetchRequest<NSFetchRequestResult> = NSFetchRequest(entityName: "Reminders")

let results = try? managedContext.fetch(fetchRequest)

storedReminders = results as! [NSManagedObject]
print(storedReminders.count)
//print(storedReminders[0].value(forKey: "reminderID"))
if (storedReminders.count > 0){
    for index in 0 ... storedReminders.count - 1{
        print("Loading reminder with ID : ")
        print(storedReminders[index].value(forKey: "reminderID"))
        print("Loading reminder with Name : ")
        print(storedReminders[index].value(forKey: "reminderName"))

        if(storedReminders[index].value(forKey: "reminderID") != nil && storedReminders[index].value(forKey: "reminderName") != nil && storedReminders[index].value(forKey: "reminderDescription") != nil && storedReminders[index].value(forKey: "reminderDate") != nil){ //checking that the values are not null
            let loadedReminder = Reminder()
            loadedReminder.reminderID = storedReminders[index].value(forKey: "reminderID") as! Double
            loadedReminder.reminderName = storedReminders[index].value(forKey: "reminderName") as! String
            loadedReminder.reminderDescription = storedReminders[index].value(forKey: "reminderDescription") as! String
            loadedReminder.reminderDate = (storedReminders[index].value(forKey: "reminderDate") as! NSDate) as Date!
            reminders.append(loadedReminder)
        }else{
                //delete this reminder
                managedContext.delete(storedReminders[index] as NSManagedObject)
                print("deleted data")
            }
    }
}

}

Upvotes: 1

Views: 356

Answers (1)

James Zaghini
James Zaghini

Reputation: 4001

Here you are creating a new Reminders instance and adding it to the NSManagedObjectContext

let entity =  NSEntityDescription.entity(forEntityName: "Reminders", in:managedContext!)
let reminderDB = NSManagedObject(entity: entity!, insertInto: managedContext)

Then you check if it's already added with:

if(checkForReminder(newReminder) == -1)

This is where I think the issue is. You have already added the Reminders instance to your context! So managedContext?.hasChanges will be true.

There are changes to the context and these Reminders will be saved with all your entities attributes with their default values. I assume they default to nil.

This should fix it, although there's parts of your code I can't see so take it with a grain of salt...

func addReminderToCalendar(newReminder: Reminder) {
    if(newReminder.reminderID != nil && newReminder.reminderDate != nil && newReminder.reminderDescription != nil && newReminder.reminderName != nil) {
        if(checkForReminder(newReminder) == -1) {
            let appDelegate = UIApplication.shared.delegate as! AppDelegate!
            let managedContext = appDelegate?.managedObjectContext
            let entity =  NSEntityDescription.entity(forEntityName: "Reminders", in:managedContext!)
            let reminderDB = NSManagedObject(entity: entity!, insertInto: managedContext)
            reminderDB.setValue(newReminder.reminderID, forKey: "reminderID")
            reminderDB.setValue(newReminder.reminderName, forKey: "reminderName")
            reminderDB.setValue(newReminder.reminderDescription, forKey: "reminderDescription")
            reminderDB.setValue(newReminder.reminderDate, forKey: "reminderDate")
            reminders.append(newReminder)

            if (managedContext?.hasChanges)! {
                do {
                    try managedContext?.save()
                } catch {
                    NSLog("Error Here")
                }
            }
        }
    } else {
        print("The reminder to be added was nil")
    }
}

Upvotes: 1

Related Questions