UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

Editing a Core Data Object

Forums > SwiftUI

Hi Everyone,

I have a environment object that is saved to coredata. How can I update new user entered values to the same core data Entity?

2      

@Bnerd  

Ok, considering your DataController is in place and you can succesfully demonstrate the results of your CoreData using somewhere in your ContentView (let's assume ContentView) a ForEach..using the example of the Dice App you could have the below

Your Entity

Your example results calling in the ContentView

@Environment(\.managedObjectContext) var diceData 
@FetchRequest(sortDescriptors: [NSSortDescriptor(key: "date", ascending: false)]) var dices: FetchedResults<Dice>

Your ForEach

ForEach(dices) { res in            
Text("\(res.diceOne ?? "-") + \(res.diceTwo ?? "-")")
}

using as an example a .onTapGesture you could modify each istance(result) of the Dice like this

Text("\(res.diceOne ?? "-") + \(res.diceTwo ?? "-")").onTapGesture {
res.diceOne = "00"
res.diceTwo = "000"
try? diceData.save()
}

The above is the main idea, you can play around as needed :) I hope it makes some sense..

2      

Hi, thank you for your reply.

However, I am still having some trouble with my code:

I have a NavigationView{

Create a new project > takes to a project details page

List {

saved projects from coredata - that I would like to edit -> takes to a projects details page

}

}

Essentially, I would like the project details values to populate from coredata but no luck. I have a feeling it may be due to my DataController.swift

import CoreData
import Foundation

//This will create an object that will persist as long as our App is open.

class DataController: ObservableObject {
    let container = NSPersistentContainer(name:"PrjoectPlanner")

    //Loading the data into a container from persisted storage.

    init() {
        container.loadPersistentStores{ description, error in
            if let error = error{
                print("Core Data failed to load: \(error.localizedDescription) ")
                return
            }
            self.container.viewContext.mergePolicy = NSMergePolicy.mergeByPropertyObjectTrump
        }
    }
}

2      

@Bnerd  

Your DataController looks fine to me. I guess you have a detailedView somewhere, how do you try to pass from the ContentView to your DetailView?

2      

As you can see, under the

List{ ForEach...}

I have to inject an environment object. How can I load that specific savedProject from coredata?


import CoreData
import SwiftUI
import Combine

struct ProjectsListView: View {

    @State private var searchText = ""

    @Environment(\.managedObjectContext) var moc
    @FetchRequest(sortDescriptors: []) var savedProject: FetchedResults<Project>

    @StateObject private var projectFile = ProjectFile()

    //@EnvironmentObject var projectFile: ProjectFile

    //this allows search from fetched results (coredata)
    var query: Binding<String> {
        Binding {
            searchText
        } set: { newValue in
            searchText = newValue
            if newValue.isEmpty {
                savedProject.nsPredicate = NSPredicate(value: true)
            } else {
                savedProject.nsPredicate = NSPredicate(format: "projectName CONTAINS[cd] %@ OR pic CONTAINS[cd] %@ OR  crewMembers CONTAINS[cd] %@", newValue, newValue,newValue)            }
        }
    }

    var body: some View {
        NavigationStack{
            Form {
                Section{
                    NavigationLink{
                        NewProject().environmentObject(projectFile)
                    } label: {
                        Text("Create a new project")
                    }
                    Text("The Count is \(savedProject.count)")

                }
                List {
                    ForEach(savedProject) { project in
                        NavigationLink {
                            //Text(project.projectName ?? "Unknown Title")
                            //Default below:
                            //ProjectDetailView(project: project)

                            //trying this out
                            EditProjectView().environmentObject(savedProject)
                        } label: {
                            HStack(alignment: .firstTextBaseline) {
                                VStack(alignment: .leading) {
                                    Text(project.projectName ?? "Unknown Title")
                                        .font(.headline)

                                }
                                Spacer()
                                Image(systemName: "airplane")

                            }.searchable(text: query)
                        }
                    }.onDelete(perform: deleteProjects)

                }

            }
            .navigationTitle("My Projects")
            .toolbar{
                ToolbarItem(placement: .navigationBarTrailing) {
                    EditButton()
                }

            }
        }
    }

    func deleteProjects(at offsets: IndexSet) {
        for offset in offsets {
            // find this book in our fetch request
            let project = savedProject[offset]

            // delete it from the context
            moc.delete(project)
        }
        // save the context
        try? moc.save()
    }
}

struct ProjectsListView_Previews: PreviewProvider {
    static var previews: some View {
        ProjectsListView()
    }
}

2      

@Bnerd  

I am not sure I know how to do it with injecting the fetchedRequest result, but a way that would work with your code is that if you modify your EditProjectView to receive a Project (Where Project I guess is your CoreData entity). Then your NavigationLink will be:

 ForEach(savedProject) { project in
 NavigationLink {  
EditProjectView(project)
}

2      

Hacking with Swift is sponsored by RevenueCat

SPONSORED Take the pain out of configuring and testing your paywalls. RevenueCat's Paywalls allow you to remotely configure your entire paywall view without any code changes or app updates.

Learn more here

Sponsor Hacking with Swift and reach the world's largest Swift community!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.