How to Add Core Data Support to An Existing Project

Sometimes, we want to add Core Data support to an existing project, you need to do two things manually.

Create a Data Model File

  1. Choose File > New > File.
  2. Choose Data Model in the iOS tab.
  3. Give a name to the Data Model file.
Create a Data Model file

Create a file named Persistence.swift

Create a file named Persistence.swift in your project, and paste code below.

import CoreData

struct PersistenceController {
    static let shared = PersistenceController()

    static var preview: PersistenceController = {
        let result = PersistenceController(inMemory: true)
        let viewContext = result.container.viewContext
        for _ in 0..<10 {
            // Init test data ...
        }
        do {
            try viewContext.save()
        } catch {
            // Replace this implementation with code to handle the error appropriately.
            // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
            let nsError = error as NSError
            fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
        }
        return result
    }()

    let container: NSPersistentContainer

    init(inMemory: Bool = false) {
        container = NSPersistentContainer(name: "<< Data Model filename without extension >>")
        if inMemory {
            container.persistentStoreDescriptions.first!.url = URL(fileURLWithPath: "/dev/null")
        }
        container.loadPersistentStores(completionHandler: { (storeDescription, error) in
            if let error = error as NSError? {
                // Replace this implementation with code to handle the error appropriately.
                // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.

                /*
                Typical reasons for an error here include:
                * The parent directory does not exist, cannot be created, or disallows writing.
                * The persistent store is not accessible, due to permissions or data protection when the device is locked.
                * The device is out of space.
                * The store could not be migrated to the current model version.
                Check the error message to determine what the actual problem was.
                */
                fatalError("Unresolved error \(error), \(error.userInfo)")
            }
        })
    }
}

Notice that, replace “<< Data Model filename without extension >>” with your Data Model filename without extension.

Attach Managed Object Context to the Environment Under the .managedObjectContext Key

Once your managed object context is attached to the environment under the .managedObjectContext key, you can use the @FetchRequest property wrapper to make properties in your views that create and manage Core Data fetch requests automatically.

import SwiftUI

@main
struct FetchRequestApp: App {
    
    let persistenceController = PersistenceController.shared

    var body: some Scene {
        WindowGroup {
            ContentView()
                .environment(\.managedObjectContext, persistenceController.container.viewContext)
        }
    }
}

By now, we have added Core Data support to our SwiftUI project. Then, we add an entity and some test data for preview. Finally, we fetch test data from Core Data store by @FetchRequest property wrapper in preview mode.

Create An Entity

An entity is a description of the data stored in Core Data store. Usually, it defines attributes/properties for a data type. If you are not familiar with Core Data, but know about the relational database, you can read my blog 4 Differences Between Core Data and SQLite You Should Know to learn about what the entity is.

Firstly, select the Data Model file we just created in the project explorer.

Choose Data Model file

Next, press the Add Entity button, and a new Entity is listed in the Entities section. Rename it to Student.

Create a new entity

Next, add two attributes gender and name with String type.

Add attributes

By now, we have defined our data model in Core Data. And we will generate test data for preview in the next section.

Generate Test Data for Preview

Open the Persistence.swift and locate to the comment “Init test data”. Add the following code under the comment.

let newItem = Student(context: viewContext)
newItem.name = "Hello Kitty"
newItem.gender = "Female"

After that, we get ten duplicated Student items for user interface preview in the canvas.

Develop User Interface with Preview Data

Attach the preview managed object context to the ContentView in the preview struct as below.

Display preview data in canvas
struct ContentView_Previews: PreviewProvider {
    
    static var previews: some View {
        ContentView()
            .environment(\.managedObjectContext, PersistenceController.preview.container.viewContext)
    }
}

SwiftUI and Xcode are awesome! We can design and debug beautiful user interface without having to start a simulator or a device. It’s very efficient and effective.

2 comments

Leave a Reply

Your email address will not be published. Required fields are marked *