With the recent changes to allow for an app to be completely in SwiftUI, I am trying to re-create a simple core data and SwiftUI app.
How can a NSPresistantContainer be setup with the new app delegate adaptor and scene builder? I have attempted what has worked previously by creating a lazy var in the app delegate and then providing that as an adaptor on the app struct.
What is the correct way to setup the NSPresistantContainer so the NSManagedObjectModel is loaded?
class AppDelegate: NSObject, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
if isDataSet() == false {
setDefaultData()
}
return true
}
lazy var persistentContainer: NSPersistentContainer = {
let container = NSPersistentContainer(name: "breakapp")
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
})
return container
}()
func saveContext () {
let context = persistentContainer.viewContext
if context.hasChanges {
do {
try context.save()
} catch {
let nserror = error as NSError
fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
}
}
}
func setDefaultData() {
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return }
let managedContext = appDelegate.persistentContainer.viewContext
for (i, weekday) in Constants.CoreData.weekdays.enumerated() {
let user = NSManagedObject(entity: Weekday.entity(), insertInto: managedContext)
user.setValue("\(weekday)", forKey: Constants.CoreData.Attributes.label)
user.setValue(i, forKey: Constants.CoreData.Attributes.sortNumber)
}
try? managedContext.save()
}
func isDataSet() -> Bool {
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return true }
let managedContext = appDelegate.persistentContainer.viewContext
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: Constants.CoreData.Entities.weekday)
let result = try? managedContext.fetch(fetchRequest)
return result?.count != 0
}
}
@main
struct TakeABreakApp: App {
@UIApplicationDelegateAdaptor private var appDelegate: AppDelegate
@Environment(\.scenePhase) private var scenePhase
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
struct TakeABreakApp_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}