Post

Replies

Boosts

Views

Activity

How to replace tabBar with bottomBar with smooth animation in SwiftUI?
I am trying to replace the navigation tab bar with a custom bottom toolbar when a view enters edit mode. Currently, I am using the following code to achieve this: content .toolbar(isEditing ? .hidden : .visible, for: .tabBar) . toolbar(isEditing ? .visible : .hidden, for: .bottomBar) However, this results in a janky animation. When the bottom bar appears, it animates in above (in contrast to in place of) the tab bar, then "jumps" back down to the correct offset without animation. I had to workaround this by delaying the appearance of bottom bar by 0.3s. I am already using withAnimation(). Is this a bug or am I using the APIs incorrectly? Is there a more seamless way to achieve this switching effect other than delaying the bottom bar? Thanks!
6
3
1k
Jul ’24
Core Data crashes when attempting to establish relationship to an entity with derived attribute in the background
I have recently moved some of my data save operations from the view context to background contexts. Since the switch, some (but not all) of my users are reporting that the background save operations crash 100% of the time. After researching, I have narrowed it down to the fact that these save operations involve establishing a relationship to an entity with a derived attribute. An example is shown below: try await CoreDataStack.shared.performBackgroundTask { context in var transaction = Transaction(context: context) transaction.amount = NSDecimalNumber(decimal: 0) transaction.id = UUID() let account = Account.account(withName: "Default", in: context) transaction.account = account try context.save() } // <= Crashes! In the above example, each Transaction has a to-one relationship to an Account, and the latter has a to-many relationship the the former. Account has a derived attribute called balance that is calculated using the expression sum:(transactionItems.amount). The would then crash when the performBackgroundTask block exits (after the save() operation returns): Thread 4 Crashed: 0 libobjc.A.dylib 0x00000001850ae00c objc_release_x8 + 8 1 CoreData 0x00000001900d8cfc -[_CDSnapshot dealloc] + 72 (_CDSnapshot.m:691) 2 CoreData 0x00000001900d8b68 _NSQLRow_dealloc_standard + 48 (NSSQLRow.m:156) 3 CoreFoundation 0x0000000187d72228 __CFBasicHashRemoveValue + 192 (CFBasicHash.c:1332) 4 CoreFoundation 0x0000000187d7212c CFBasicHashRemoveValue + 452 (CFBasicHash.c:1418) 5 CoreFoundation 0x0000000187d71638 CFDictionaryRemoveValue + 196 (CFDictionary.c:477) 6 CoreData 0x00000001900f6fa8 -[NSPersistentStoreCache decrementRefCountForObjectID:] + 96 (NSPersistentStoreCache.m:120) 7 CoreData 0x00000001900f6eec -[NSSQLCore managedObjectContextDidUnregisterObjectsWithIDs:generation:] + 172 (NSSQLCore.m:4329) 8 CoreData 0x00000001900f30f4 0x1900d6000 + 119028 9 CoreData 0x00000001900f4d74 gutsOfBlockToNSPersistentStoreCoordinatorPerform + 204 (NSPersistentStoreCoordinator.m:404) 10 libdispatch.dylib 0x000000018fe9b0d8 _dispatch_client_callout + 20 (object.m:576) 11 libdispatch.dylib 0x000000018fea26e0 _dispatch_lane_serial_drain + 744 (queue.c:3934) 12 libdispatch.dylib 0x000000018fea31e8 _dispatch_lane_invoke + 380 (queue.c:4025) 13 libdispatch.dylib 0x000000018feae258 _dispatch_root_queue_drain_deferred_wlh + 288 (queue.c:7185) 14 libdispatch.dylib 0x000000018feadaa4 _dispatch_workloop_worker_thread + 532 (queue.c:6779) 15 libsystem_pthread.dylib 0x000000020f3c0c7c _pthread_wqthread + 288 (pthread.c:2696) 16 libsystem_pthread.dylib 0x000000020f3bd488 start_wqthread + 8 performBackgroundTask is defined as: func performBackgroundTask<T>(_ block: @escaping (NSManagedObjectContext) throws -> T) async rethrows -> T { try await container.performBackgroundTask { context in context.transactionAuthor = appTransactionAuthorName context.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy return try block(context) } } Things to note: If I do not establish the relationship to Account from Transaction, the crash doesn't happen; if I uncheck derived on the balance attribute of Account, the crash also does not happen. For those users who are experiencing the crash, the crash rate is 100%; for those who aren't experiencing the crash, the crash never happens. So it's either 100% or 0%. I have double checked all concurrency usages and all operations are performed within NSPersistentCloudKitContainer's performBackgroundTaskmethod, so it's probably not a threading issue. I have also tried ASan, Core Data's concurrency debug, as well as Zombie objects to no avail. The crash seems to be related to a user's existing data. While I couldn't reproduce the crash on my own database, once I replaced the underlying SQLite file with one of my crashing user's, the crash is 100% reproducible. I am at my wit's end here. Is this an internal Core Data bug, or am I doing something incorrectly? Any help is greatly appreciated!
3
3
1.1k
Jul ’24
How to stop current symbolEffect before contentTransition?
Currently I have a cloud syncing status icon that utilizes the new "rotate" symbol effect introduced with iOS 18. After the synchronization is complete, I want to replace the icon with another symbol using the "replace" contentTransition. These are the codes I used to achieve this: Image(systemName: coreDataStack.cloudKitUIStatus.symbolName) .foregroundColor(coreDataStack.cloudKitUIStatus.symbolColor) .symbolEffect(.rotate, isActive: coreDataStack.cloudKitUIStatus == .inProgress) .contentTransition(.symbolEffect(.replace)) However, the rotation effect continues after the replace transition. This means the new icon (checkmark.icloud.fill) continues the spinning animation from the previous symbol (arrow.triangle.2.circlepath.icloud) until it completes the full circle. How can I stop the rotation immediately before the contentTransition? Thanks!
0
4
670
Jun ’24