Login required for access
In order to watch this lesson, you'll need to login to the website.

To illustrate the saving of objects in Core Data, we'll be going over how to create new Entity objects as well as some persistence code. Eventually you'll be able to save and delete objects with the press of a few buttons:

Go ahead and open your core data xcdatamodeld file and add the following Card entity:

Once your entity is entered, go the the Editor menu and hit Create NSManagedObject Subclass:

This will generate the necessary classes in your Xcode project. With Xcode 12+, you can actually delete these files since they are managed by Xcode automatically.

Finally, make the following updates:
struct MainView: View {    @State private var shouldPresentAddCardForm = false    // 1    @Environment(\.managedObjectContext) private var viewContext    // 2    @FetchRequest(        sortDescriptors: [NSSortDescriptor(keyPath: \Card.timestamp, ascending: true)],        animation: .default)    private var cards: FetchedResults<Card>    var body: some View {        NavigationView {            ScrollView {                // 3                if !cards.isEmpty {                    TabView {                        ForEach(cards) { card in                            CreditCardView()                                .padding(.bottom, 50)                        }                    }                    // ...                }                Spacer()                    .fullScreenCover(isPresented: $shouldPresentAddCardForm, onDismiss: nil) {                        AddCardForm()                    }            }            .navigationTitle("Credit Cards")            .navigationBarItems(leading: HStack {                addItemButton                deleteAllButton            },                                trailing: addCardButton)        }    }    private var deleteAllButton: some View {        Button {            cards.forEach { card in                viewContext.delete(card)            }            do {                try viewContext.save()            } catch {            }        } label: {            Text("Delete All")        }    }    // 4    var addItemButton: some View {        Button(action: {            withAnimation {                let viewContext = PersistenceController.shared.container.viewContext                let card = Card(context: viewContext)                card.timestamp = Date()                do {                    try viewContext.save()                } catch {                    // error handling                }            }        }, label: {            Text("Add Item")        })    }}struct MainView_Previews: PreviewProvider {    static var previews: some View {        let viewContext = PersistenceController.shared.container.viewContext        MainView()            // 5            .environment(\.managedObjectContext, viewContext)    }}
  1. In order for a @FetchRequest to execute in SwiftUI, your view needs to be injected with a managedObjectContext, otherwise Core Data has no way of fetching entities.
  2. SwiftUI supports @FetchRequest which automatically fires after your view is created. Additional initializers can be found here: FetchRequest documentation. The next line determines what entities are fetched using the FetchResults<T> generic where T in this case is Card. A nice feature of @FetchRequest is that it automatically updates whenever changes are introduced to Core Data.
  3. First check if cards is not empty, then render out your TabView component. Failing to do this will lead to a crash since TabView requires a non empty content @ViewBuilder.
  4. To persist objects into Core Data, you simply need to create your Entity using the Entity(context:) constructor. Set your properties to the necessary values and call save() to commit your changes.
  5. Inject your view with a proper viewContext. Without this, your MainView will not be able to fire off its @FetchRequest

Comments (0)