Posts

Post not yet marked as solved
1 Replies
768 Views
In my app I have a defaultJournal: Journal, that automatically gets added on the user's device on launch. There should only be one "default" journal, and I know that deduplication as shown in the Apple Demo, is the correct approach to ensure this on multiple devices. Journal looks something like: class Journal: NSManagedObject { @NSManaged var isDefaultJournal: Bool @NSManaged var entries: Set<JournalEntry>? } Since Journal has a relationship to entries, how can I deduplicate it ensuring that I don't orphan or delete the entries? I am worried that the entries aren't guaranteed to be synced, when we discover a duplicate journal in processPersistentHistory. This would lead to either orphaned or deleted entries depending on the deletion rule. How can one handle deduplicating entities with relationships? For example here is my remove function:     func remove(duplicateDefaultCalendarNotes: [Journal], winner: Journal, on context: NSManagedObjectContext) {         duplicateDefaultCalendarNotes.forEach { journal in             defer { context.delete(journal) } // FIXME: What if all of the journal entries have not been synced yet from the cloud? // Should we fetch directly from CloudKit instead? (could still lead to orphaned/deleted journal that have not yet been uploaded)             guard let entries = journal.entries else { return }             entries.forEach {                 $0.journal = winner             }         }     } A missing tag on a post isn't that bad, but deleting a user's journal is unacceptable. What is the best strategy to handle this?
Posted
by mikeyM.
Last updated
.
Post not yet marked as solved
0 Replies
570 Views
Does anyone know what could be causing this? App uses SwiftUI App lifecycle. Xcode: 12.5.1 iPad: 14.8 Trace: * thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x0)     frame #0: 0x00000001beb39198 AttributeGraph`AG::Subgraph::cache_insert(AG::data::ptr<AG::Node>) + 120     frame #1: 0x00000001beb331fc AttributeGraph`AG::Graph::remove_node(AG::data::ptr<AG::Node>) + 108     frame #2: 0x00000001beb36b38 AttributeGraph`AG::Subgraph::invalidate_now(AG::Graph&, unsigned long) + 960     frame #3: 0x00000001beb372ac AttributeGraph`AG::Subgraph::invalidate_and_delete_(bool) + 264     frame #4: 0x000000019e5039f4 SwiftUI`closure #1 () -> () in SwiftUI.GraphHost.uninstantiate() -> () + 20     frame #5: 0x000000019e074f40 SwiftUI`reabstraction thunk helper from @escaping @callee_guaranteed () -> () to @escaping @callee_guaranteed () -> (@out ()) + 20     frame #6: 0x000000019e061234 SwiftUI`static SwiftUI.Update.end() -> () + 496     frame #7: 0x000000019e502c0c SwiftUI`SwiftUI.GraphHost.uninstantiate() -> () + 396   * frame #8: 0x000000019e04ee6c SwiftUI`SwiftUI.ViewGraph.didChangePreferenceBridge(from: Swift.Optional<SwiftUI.PreferenceBridge>) -> () + 100     frame #9: 0x000000019e04e9e8 SwiftUI`SwiftUI.ViewGraph.preferenceBridge.setter : Swift.Optional<SwiftUI.PreferenceBridge> + 56     frame #10: 0x000000019e5bebd0 SwiftUI`SwiftUI._UIHostingView.__deallocating_deinit + 216     frame #11: 0x000000019e5bec08 SwiftUI`@objc SwiftUI._UIHostingView.__deallocating_deinit + 24     frame #12: 0x00000001ab8e139c libobjc.A.dylib`AutoreleasePoolPage::releaseUntil(objc_object**) + 200     frame #13: 0x00000001ab8e1278 libobjc.A.dylib`objc_autoreleasePoolPop + 208     frame #14: 0x000000019acba600 QuartzCore`CA::Context::commit_transaction(CA::Transaction*, double, double*) + 636     frame #15: 0x000000019ace52c8 QuartzCore`CA::Transaction::commit() + 668     frame #16: 0x000000019ace6530 QuartzCore`CA::Transaction::observer_callback(__CFRunLoopObserver*, unsigned long, void*) + 92     frame #17: 0x0000000197ac3c40 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 32     frame #18: 0x0000000197abe270 CoreFoundation`__CFRunLoopDoObservers + 588     frame #19: 0x0000000197abe80c CoreFoundation`__CFRunLoopRun + 1012     frame #20: 0x0000000197abded0 CoreFoundation`CFRunLoopRunSpecific + 572     frame #21: 0x00000001ae207570 GraphicsServices`GSEventRunModal + 160     frame #22: 0x000000019a3eb2d0 UIKitCore`-[UIApplication _run] + 1052     frame #23: 0x000000019a3f084c UIKitCore`UIApplicationMain + 164     frame #24: 0x000000019e499530 SwiftUI`closure #1 (Swift.UnsafeMutablePointer<Swift.Optional<Swift.UnsafeMutablePointer<Swift.Int8>>>) -> Swift.Never in SwiftUI.KitRendererCommon(Swift.AnyObject.Type) -> Swift.Never + 108     frame #25: 0x000000019e4994c0 SwiftUI`SwiftUI.runApp<τ_0_0 where τ_0_0: SwiftUI.App>(τ_0_0) -> Swift.Never + 176     frame #26: 0x000000019e04a870 SwiftUI`static SwiftUI.App.main() -> () + 96     frame #27: 0x000000010244cb60 Pencil it in`static PIIApp.$main(self=Pencil_it_in.PIIApp) at PIIApp.swift:13:1     frame #28: 0x000000010244cc18 Pencil it in`main at PIIApp.swift:0     frame #29: 0x000000019779c140 libdyld.dylib`start + 4
Posted
by mikeyM.
Last updated
.
Post not yet marked as solved
3 Replies
895 Views
Failure to Load Persistent Stores How are we supposed to handle this with Widgets? I can't reproduce the issue, and in my App Target I usually just fatalError, which has resulted in very few if any crashes in production. However, since implementing my widget, I am getting hundreds of crash reports a day in my Widget target due to this. I have added logging, but have yet to receive a log or even a user complaint, so I don't know exactly what error is being produced. I am guessing it's a memory issue, or maybe a dataProtection issue. When I build my Widget the console outputs: [error] warning: Force checkpointing -wal while initializing query generations due to its large size (134225512) which I assume means it's a memory issue. I am instantiating my NSPersistentContainer in my TimeLineProvider What is the best way to handle this? Should I just remove the fatalError? Do I need to mirror only what's necessary from my store to a smaller json file and only share that with the widget?
Posted
by mikeyM.
Last updated
.
Post not yet marked as solved
1 Replies
1.2k Views
I have a model that has already been pushed to production, and I would like to move an attribute to a new entity as a relationship.From This:extension Note { @NSManaged public var drawingData: Data? .... }To This: extension Note { @NSManaged public var drawing: Drawing? .... } extension Drawing { @NSManaged public var drawingData: Data? .... }According to the Apple Docs under the "Update your Production Schema" section, I will need to migrate to a new CloudKit Container, since we can't delete attributes on "production" CKRecords.What is the proper workflow to do this?I have come up with the following, but I believe it is wrong.lazy var oldPersistentContainer: NSPersistentCloudKitContainer = { let container = NSPersistentCloudKitContainer(name: "Model") let storeLocation = URL(fileURLWithPath: "/path/to/cloud.store") let storeDescription = NSPersistentStoreDescription(url: storeLocation) // Set the container options on the cloud store cloudStoreDescription.cloudKitContainerOptions = NSPersistentCloudKitContainerOptions( containerIdentifier: "com.myCompany.myApp") container.loadPersistentStores... ... }() /// NOTE: - `containerIdentifier` has been "bumped" lazy var newPersistentContainer: NSPersistentCloudKitContainer = { let container = NSPersistentCloudKitContainer(name: "Model") let storeLocation = URL(fileURLWithPath: "/path/to/cloud.store") let storeDescription = NSPersistentStoreDescription(url: storeLocation) // Set the container options on the cloud store cloudStoreDescription.cloudKitContainerOptions = NSPersistentCloudKitContainerOptions( containerIdentifier: "com.myCompany.myApp2") // TODO: Migrate Core Data Store if needed container.loadPersistentStores... ... }()NOTE: newPersistentContainer would have a "bumped" containerIdentifier and it would also perform Core Data Migration.Then I think I would need to manually move all records from oldPersistentContainer and add them to newPersistentContainer. Once all the data has been moved into the new container , I would delete all records from oldPersistentContainer. Would that be enough in terms of cleaning up oldPersistentContainer?It took me a while to come up with this workflow, but I still think it is wrong. Could someone give me some insight on how to properly perform a CloudKit Container Migration with NSPersistentCloudKitContainer.
Posted
by mikeyM.
Last updated
.