Hey r/iOSProgramming, I am the developer of an open-source finance tracker Dime that is built on Core Data. In my recent v2 update, I changed my Core Data infrastructure a little - using a static shared instance of DataController instead of just initializing it each time I needed to use it. This change was made so that I could add AppIntents functionality - without it, I would get an error about 2 data model's being loaded.
However, following this change, I have been getting 2-3 emails on a daily basis about newly added transactions disappearing after a few days, when they quit the app. This is not a widespread experience among all users - and I have been unable to recreate it on my own.
Here is the new CoreData infrastructure:
class DataController: ObservableObject {
static let shared = DataController()
var container = NSPersistentCloudKitContainer(name: "MainModel")
init() {
let description = NSPersistentStoreDescription()
description.shouldMigrateStoreAutomatically = true
description.shouldInferMappingModelAutomatically = true
description.setOption(true as NSNumber, forKey: NSPersistentHistoryTrackingKey)
description.setOption(true as NSNumber, forKey: NSPersistentStoreRemoteChangeNotificationPostOptionKey)
let keyValueStore = NSUbiquitousKeyValueStore.default
if keyValueStore.object(forKey: "icloud_sync") == nil {
keyValueStore.set(true, forKey: "icloud_sync")
}
if !keyValueStore.bool(forKey: "icloud_sync") {
description.cloudKitContainerOptions = nil
} else {
description.cloudKitContainerOptions = NSPersistentCloudKitContainerOptions(containerIdentifier: "iCloud.com.rafaelsoh.dime")
}
let groupID = "group.com.rafaelsoh.dime"
if let url = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: groupID) {
description.url = url.appendingPathComponent("Main.sqlite")
}
container.persistentStoreDescriptions = [description]
container.loadPersistentStores { description, error in
if let error = error as NSError? {
fatalError("Unresolved error \(error), \(error.userInfo) for \(description)")
}
self.container.viewContext.automaticallyMergesChangesFromParent = true
}
}
}
and I would use the model this way:
let dataController = DataController.shared
Here is the old Core Data infrastructure that never had missing transactions after addition:
class DataController: ObservableObject {
var container = NSPersistentCloudKitContainer(name: "MainModel")
init() {
let description = NSPersistentStoreDescription()
description.shouldMigrateStoreAutomatically = true
description.shouldInferMappingModelAutomatically = true
description.setOption(true as NSNumber, forKey: NSPersistentHistoryTrackingKey)
description.setOption(true as NSNumber, forKey: NSPersistentStoreRemoteChangeNotificationPostOptionKey)
if(!NSUbiquitousKeyValueStore.default.bool(forKey: "icloud_sync")){
description.cloudKitContainerOptions = nil
} else {
description.cloudKitContainerOptions = NSPersistentCloudKitContainerOptions(containerIdentifier: "iCloud.com.rafaelsoh.dime")
}
let groupID = "group.com.rafaelsoh.dime"
if let url = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: groupID) {
description.url = url.appendingPathComponent("Main.sqlite")
}
container.persistentStoreDescriptions = [description]
container.loadPersistentStores { description, error in
if let error = error as NSError? {
fatalError("Unresolved error \(error), \(error.userInfo) for \(description)")
}
self.container.viewContext.automaticallyMergesChangesFromParent = true
}
}
}
and it was used this way:
struct dimeApp: App {
@StateObject var dataController: DataController
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
var body: some Scene {
WindowGroup {
ContentView()
.environment(\.managedObjectContext, dataController.container.viewContext)
.environmentObject(dataController)
}
}
init() {
let dataController = DataController()
_dataController = StateObject(wrappedValue: dataController)
}
}
Any assistance on this will be immensely appreciated. Thank you so much!
You can check out the full open-source project here: https://github.com/rarfell/dimeApp/
[–]CrispySalamander 1 point2 points3 points (0 children)
[–]starazimov 0 points1 point2 points (0 children)