You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
LeCountdown/LeCountdown/Model/Persistence.swift

125 lines
5.1 KiB

//
// Persistence.swift
// LeCountdown
//
// Created by Laurent Morvillier on 20/01/2023.
//
import CoreData
struct PersistenceController {
static let shared = PersistenceController()
static var preview: PersistenceController = {
let result = PersistenceController(inMemory: true)
let viewContext = result.container.viewContext
let activity = Activity(context: viewContext)
activity.name = "Tea"
let activity2 = Activity(context: viewContext)
activity2.name = "Running"
let activity3 = Activity(context: viewContext)
activity3.name = "Nap"
let activities = [activity, activity2, activity3]
for i in 0..<3 {
let countdown = Countdown(context: viewContext)
countdown.order = Int16(i)
countdown.activity = activity
countdown.image = CoolPic.pic1.rawValue
}
for i in 0..<20 {
let record = Record(context: viewContext)
let randomMonth = (0...10 * 31).randomElement() ?? 3
let monthTimeInterval = Double(randomMonth) * 3600 * 24
let start = Date().addingTimeInterval(-monthTimeInterval)
let duration = Double((1...10).randomElement() ?? 5) * 60.0
let end = start.addingTimeInterval(duration)
record.start = start
record.end = end
record.activity = activities.randomElement()
}
do {
try viewContext.save()
} catch {
Logger.error(error)
// 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
FileLogger.log("app terminated by ourselves")
fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
}
return result
}()
let container: NSPersistentCloudKitContainer
init(inMemory: Bool = false) {
let storeURL = URL.storeURL(for: "group.com.staxriver.countdown", databaseName: "group.com.staxriver.countdown")
let storeDescription = NSPersistentStoreDescription(url: storeURL)
storeDescription.shouldMigrateStoreAutomatically = true
storeDescription.shouldInferMappingModelAutomatically = true
let id = "iCloud.LeCountdown"
let options = NSPersistentCloudKitContainerOptions(containerIdentifier: id)
storeDescription.cloudKitContainerOptions = options
// let remoteChangeKey = "NSPersistentStoreRemoteChangeNotificationOptionKey"
// storeDescription.setOption(true as NSNumber, forKey: remoteChangeKey)
container = NSPersistentCloudKitContainer(name: "LeCountdown")
container.persistentStoreDescriptions = [storeDescription]
if inMemory {
container.persistentStoreDescriptions.first!.url = URL(fileURLWithPath: "/dev/null")
}
// do {
// try container.initializeCloudKitSchema()
// } catch {
// fatalError("Unresolved error \(error)")
// }
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.
*/
FileLogger.log("app terminated by ourselves")
fatalError("Unresolved error \(error), \(error.userInfo)")
}
})
container.viewContext.mergePolicy = NSMergeByPropertyStoreTrumpMergePolicy
container.viewContext.automaticallyMergesChangesFromParent = true
}
}
fileprivate extension URL {
/// Returns a URL for the given app group and database pointing to the sqlite database.
static func storeURL(for appGroup: String, databaseName: String) -> URL {
guard let fileContainer = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: appGroup) else {
FileLogger.log("app terminated by ourselves")
fatalError("Shared file container could not be created.")
}
return fileContainer.appendingPathComponent("\(databaseName).sqlite")
}
}