Search code examples
swiftuiparameters

How to pass parameters into an addItem function (CoreData)?


I am trying to create a notes app. I am having trouble implementing an add new note function. I want to pass in name and text as parameters. Initially the name of the note will be set (like "New note"). When I try to add parameters the project builds but does not add a new note. Any advice?

import SwiftUI

struct ContentView: View {
    
    @Environment(\.managedObjectContext) private var viewContext
    
    @FetchRequest(sortDescriptors: [NSSortDescriptor(keyPath: \Note.name, ascending: true)])
    var notes: FetchedResults<Note>
    
    @State private var NoteIds: Set<Note.ID> = []
    
    var body: some View {
        List(notes, selection: $NoteId){ note in
            Text(note.name)
        }
        .toolbar{
            ToolbarItem(placement: .primaryAction){
                Button(action: newNote){
                    Label("New Note", systemImage: "square.and.pencil")
                }
            }
        }
    }
    private func newNote(){ //add new note 
       newNote(name: "New Note", text:"")
    }
    
private func newNote(name: String, text: String) {
        withAnimation {
            let note = Note(context: viewContext)
            note.id = UUID()
            note.name = name
            note.text = text

            do {
                try viewContext.save()
            } catch {
                let nsError = error as NSError
                fatalError("Unable to create note \(nsError), \(nsError.userInfo)")
            }
        }
        
    }
}

Solution

  • Your datacontroller class I made in a demo app I created for this question

    import Foundation
    import CoreData
    
    struct DataController {
        static let shared = DataController()
        let container: NSPersistentContainer
        
        init(inMemory: Bool = false) {
            container = NSPersistentContainer(name: "NotesData")
            if inMemory {
                container.persistentStoreDescriptions.first?.url = URL(fileURLWithPath: "/dev/null")
            }
            container.loadPersistentStores { description, error in
                if let error = error {
                    fatalError("cannot load data \(error)")
                }
            }
        }
    }
    

    and your main class , I added button at bottom to add the rows , seems to work good , hope it helps

    import SwiftUI
    
    
    struct ContentView: View {
        @Environment(\.managedObjectContext) private var viewContext
           
        @FetchRequest(sortDescriptors: [NSSortDescriptor(keyPath: \Note.name, ascending: true)])
        var notes: FetchedResults<Note>
        
        @State private var NoteIds: Set<Note.ID> = []
    
        var body: some View {
            List(notes, selection: $NoteIds){ note in
                Text(note.name ?? "")
            }
    
                    Button(action: newNote){
                        Label("New Note", systemImage: "square.and.pencil")
                    }
        
            
           
            
            
        }
        
        func newNote(name: String, text: String) {
            withAnimation {
                let note = Note(context: viewContext)
                note.id = UUID()
                note.name = name
                note.text = text
                
                do {
                    try viewContext.save()
                } catch {
                    let nsError = error as NSError
                    fatalError("Unable to create note \(nsError), \(nsError.userInfo)")
                }
            }
            
        }
        
        func newNote() { //add new note
            newNote(name: "New Note", text:"")
        }
            
    }
    

    also your struct with @main

    @main
    struct DemoApp: App {
        let  dataController = DataController()
        var body: some Scene {
            WindowGroup {
                ContentView()
                    .environment(\.managedObjectContext, dataController.container.viewContext)
            }
        }
    }