Post

Replies

Boosts

Views

Activity

How to toggle CoreData CloudKit sync during App runtime
Hi, I'm currently developing a SwiftUI based app with Core Data and CloudKit sync with the NSPersistentCloudKitContainer. I found different solutions how to toggle CloudKit sync of the Core Data during runtime. The basic idea of these solutions is the following. instantiate a new NSPersistentCloudKitContainer set storeDescription.cloudKitContainerOptions = nil load persistence store Some solutions recommend to restart the app manually to avoid exactly my problem. Issues So far so good. How can I distribute the new viewContext through my app during runtime. In the main App I distributed the viewContext during startup via @Environment(\.managedObjectContext) and it seems not be updated automatically after a reinitialization of NSPersistentCloudKitContainer. var body: some Scene {   WindowGroup {             ContentView()                 .environment(\.managedObjectContext, persistence.container.viewContext)         } } After deactivating the CloudKit sync I receive the following error when I try to add a new entity. [error] warning: Multiple NSEntityDescriptions claim the NSManagedObject subclass 'TestEntity' so +entity is unable to disambiguate. Any ideas? Regards Sven
5
1
2.3k
Nov ’21
Is it possible to unload/change the PersistenceStore in a SwiftUI App during runtime
Hi, I want to activate/deactivate the CloudKit Sync during App runtime in a user settings view. Basically this works fine. Every time I toggle between the NSPersistentContainer and the NSPersistentCloudKitContainer, I increase the persistence.persistenceContainerReloaded attribute and the whole view hierarchy will be reloaded. Thus all changes are passed through the whole app. During the reload phase I have to load a new persistence store by container.loadPersistentStores(...). Unfortunately, I cannot remove the old persistence store before loading the new one. The app crashes immediately, because the store and viewContext is still in use. Therefore, I just create a new one and trigger the reload. Afterwards every view is using the new viewContext. But somewhere in the background there is still the old persistence store with CloudKit Sync active and pushes every local change to the cloud. Changes on the cloud from other devices are not received anymore. Does someone has any idea, how to correctly unload a PersistentStore (replace NSPersistentCloudKitContainer by NSPersistentContainer) in a SwiftUI based app? @main struct TargetShooterApp: App {     @StateObject var persistence: Persistence = Persistence.shared     var body: some Scene {         WindowGroup {             ContentView()                 .environment(\.managedObjectContext, persistence.container.viewContext)                 .id(persistence.persistenceContainerReloaded)         }     } }
6
2
1.1k
Dec ’21
Dynamically change sort order a SwiftUI Sectioned List
I'm trying to dynamically change the sort order to sections SwiftUI list. The Core Data model consists of an Item Entity with a group and timestamp attribute. import SwiftUI import CoreData struct ContentView: View { @Environment(\.managedObjectContext) private var viewContext @State var counter: UInt32 = 0 @State var order: SortOrder = .reverse @SectionedFetchRequest( sectionIdentifier: \.group!, sortDescriptors: [SortDescriptor(\.timestamp, order: .reverse)], predicate: nil, animation: .default ) private var items: SectionedFetchResults<String, Item> var body: some View { NavigationView { List { ForEach(items) { section in Section(header: Text("\(section.id)")) { ForEach(section) { item in NavigationLink { VStack { Text("Item at \(item.timestamp!, formatter: itemFormatter)") Text("\(item.group!)") } } label: { VStack { Text(item.timestamp!, formatter: itemFormatter) } } } } } } .navigationTitle("Sectioned List") .toolbar { ToolbarItem(placement: .primaryAction) { Button(action: addItem) { Label("Add Item", systemImage: "plus") } } ToolbarItem(placement: .principal) { Button(action: toggleSortOrder) { Label("Sort Oder", systemImage: "arrow.up.arrow.down") } } } } } private func addItem() { withAnimation { let newItem = Item(context: viewContext) newItem.timestamp = Date() newItem.group = "Group #\(counter)" counter = (counter + 1) % 3 do { try viewContext.save() } catch { let nsError = error as NSError fatalError("Unresolved error \(nsError), \(nsError.userInfo)") } } } private func toggleSortOrder() { order = order == .reverse ? .forward : .reverse items.sortDescriptors = [SortDescriptor(\.timestamp, order: order)] } } As soon as I toggle the sort order, the app crashes with the following error code. The same code with a non-sectioned list works perfectly. In UIKit applications there was a possibility to set tableView.beginUpdates()and tableView.endUpdates(). Is there any similar functions available in SwiftUI? 2022-01-24 22:09:17.323096+0100 SectionedListSortOrder[69887:2007668] *** Assertion failure in -[_UITableViewUpdateSupport _computeRowUpdates], UITableViewSupport.m:568 2022-01-24 22:09:17.347996+0100 SectionedListSortOrder[69887:2007668] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'UITableView internal inconsistency: encountered out of bounds global row index while preparing batch updates (oldRow=8, oldGlobalRowCount=8)'
2
0
2.9k
Jan ’22
Charts Framework: chartYScale(domain:) scales the y-axis correctly but BarMarks are drawn down to bottom part of the screen
I'm testing the the new Charts Framework from Apple with Xcode 14.0 Beta 2. But I face some strange issues when I try to scale the y-axis to some concrete values. var body: some View {         VStack {             GroupBox("Serien") {                 Chart {                     ForEach(seriesData) { series in                         BarMark(                             x: .value("Series", series.name),                             y: .value("Wert", series.value)                         )                         .cornerRadius(8.0)                         .annotation(position: .overlay, alignment: .top, spacing: 10.0) {                             Text("\(series.value)")                                 .foregroundColor(.white)                                 .fontWeight(.bold)                         }                     }                     RuleMark(y: .value("Durchschnitt", shotResult.wrappedSeriesAsInt.mean()))                         .foregroundStyle(.red)                 }                 .chartYScale(domain: minSeriesYAxis...maxSeriesYAxis)                 .frame(height: 220, alignment: .topLeading)             }             .backgroundStyle(Color.white)             .shadow(radius: 5.0, x: 2.0, y: 2.0)         }     } Resulting View The LineMark or RectangleMark looks ok. But e.g. the AreaMark has the same issue.
4
3
3.3k
Jun ’22