skip to Main Content

I followed this tutorial
https://www.youtube.com/watch?v=35mKM4IkHS8&lc=UgztyK4XjUuAOrKk0XJ4AaABAg.9LtwRc_M0Gv9Nt8GIlAzDo

Basically I made a NotePad App that has a core data save function.
I made this app on another view controller
So There is MainViewController > NoteViewViewController
The first time I click the notepad section it loads core data perfectly well, but if I close out the NoteView and reopen it — it duplicates all the saved Notes in Core Data
Here is the. Note ViewController

import UIKit
import CoreData

var noteList = [Note]()


class NoteTableView: UITableViewController


{
    
    
    
    func nonDeletedNotes() -> [Note]
    {
        var noDeleteNoteList = [Note]()
        for note in noteList
        {
            if(note.deletedDate == nil)
            {
                noDeleteNoteList.append(note)
            }
        }
        return noDeleteNoteList
    }
    
    
    var firstLoad = true
    
    override func viewDidLoad() {
        
        if(firstLoad == true)
        
        
        {
            firstLoad = false
            let appDelegate = UIApplication.shared.delegate as! AppDelegate
            let context: NSManagedObjectContext = appDelegate.persistentContainer.viewContext
            let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Note")
            do {
                let results:NSArray = try context.fetch(request) as NSArray
                for result in results
                {
                    let note = result as! Note
                    noteList.append(note)
                }
            }
            catch
            {
                print("Fetch Failed")
            }
            
        }
    }
    
    
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) ->
    UITableViewCell
    {
    
        let noteCell = tableView.dequeueReusableCell(withIdentifier: "noteCellID", for: indexPath) as! NoteCell
        
        let thisNote: Note!
        thisNote = nonDeletedNotes()[indexPath.row]
        
        noteCell.titleLabel.text = thisNote.title
        noteCell.descLabel.text = thisNote.desc1
        
        return noteCell
        
    }
   
    
    
    
    
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
    {
        return nonDeletedNotes().count
    }
    override func viewDidAppear(_ animated: Bool) {
        tableView.reloadData()
    }
    
    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
    {
        self.performSegue(withIdentifier: "editNote", sender: self)
    }
    override func prepare(for segue: UIStoryboardSegue, sender: Any?)
    {
        if(segue.identifier == "editNote")
        {
            let indexPath = tableView.indexPathForSelectedRow!
            
            let noteDetail = segue.destination as? FocusWheelViewController
            
            let selectedNote : Note!
            selectedNote = nonDeletedNotes()[indexPath.row]
            noteDetail!.selectedNote = selectedNote
            
            tableView.deselectRow(at: indexPath, animated: true)
        }
    }
  
}
    

I’m sure there is a common solution but I’m not sure what it is and wasn’t able to follow the posts asking similar questions as my code was different and I truthfully don’t understand the mechanics well enough to apply other answers to this

2

Answers


  1. Chosen as BEST ANSWER

    I found the easiest solution was to just add these two lines so the table view refreshed every-time, then loaded the data

    noteList.removeAll()
    tableView.reloadData()
    

    So the code looks something like this:

     var firstLoad = true
        
        override func viewDidLoad() {
            
            if(firstLoad == true)
            
            
            {
                noteList.removeAll() //NEWCODE
                tableView.reloadData() //NEWCODE
                firstLoad = false
                let appDelegate = UIApplication.shared.delegate as! AppDelegate
                let context: NSManagedObjectContext = appDelegate.persistentContainer.viewContext
                let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Note")
                do {
                    let results:NSArray = try context.fetch(request) as NSArray
                    for result in results
                    {
                        let note = result as! Note
                        noteList.append(note)
                    }
                }
                catch
                {
                    print("Fetch Failed")
                }
                
            }
        }
    

  2. The problem is var firstLoad = true. Because every time the controller start, firtLoad always true and the app will get data from Coredata and append to noteList.

    The solution is UserDefaults. The first time when you run app, firstLoad always true. So you need to save the value bool of firstLoad to UserDefaults

    // Set
    UserDefaults.standard.setValue(true, forKey: "firstLoad")
    // Get
    UserDefaults.standard.bool(forKey: "firstLoad")
    
    
    import UIKit
    import CoreData
    
    class NoteTableView: UITableViewController{
        
        var noteList = [Note]()
        func nonDeletedNotes() -> [Note]{
            var noDeleteNoteList = [Note]()
            for note in noteList {
                if(note.deletedDate == nil) {
                    noDeleteNoteList.append(note)
                }
            }
            return noDeleteNoteList
        }
        
        override func viewDidLoad() {
            if noteList.count == 0 {
                if(UserDefaults.standard.bool(forKey: "firstLoad") == true){
                    let appDelegate = UIApplication.shared.delegate as! AppDelegate
                    let context: NSManagedObjectContext = appDelegate.persistentContainer.viewContext
                    let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Note")
                    do {
                        let results:NSArray = try context.fetch(request) as NSArray
                        for result in results
                        {
                            let note = result as! Note
                            noteList.append(note)
                            UserDefaults.standard.setValue(false, forKey: "firstLoad")
                        }
                    }
                    catch {
                        print("Fetch Failed")
                    }
                    
                }
            } {
                else {
                    UserDefaults.standard.setValue(false, forKey: "firstLoad")
                }
            }
            
        }
    }
    

    And maybe you need to check duplicate value when get data from CoreData.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search