SwiftData

RSS for tag

SwiftData is an all-new framework for managing data within your apps. Models are described using regular Swift code, without the need for custom editors.

Posts under SwiftData tag

200 Posts
Sort by:

Post

Replies

Boosts

Views

Activity

Swift Data - fail gracefully if file can't be opened
Hello By default if swiftData is unable to open a file on mac (due to it being the wrong format, or an old model) the app hard crashes (macOS 14.4.1) - is there a way to catch this problem and present a message to the user, rather than the app simply crashing The whole way that swiftData opens files etc is very opaque so I'm not clear how we can wrap things in a nice way Thanks Richard
0
0
17
1h
Swift Data crashing on close document
Hello I have a swiftUI/swiftData document based app. In this I have created a singleton object using the folllowing in my ContentView struct: @Query private var persistantStores:[PersistantStateManagerStorage] @State private var stateManager: PersistantStateManagerStorage? I then, call the following on the onAppear and onDisappear calls on the top level HStack{} item in my view .onAppear(){ if let store = persistantStores.first { self.stateManager = store // data.first } else { self.stateManager = PersistantStateManagerStorage() modelContext.insert(stateManager!) try? modelContext.save() } }.onDisappear(){ print("bye bye") self.stateManager = nil } I then wrap my view inside a if let stateManager = stateManager {} block to unwrap the optional, and bind to values with a call such as Stepper("Nudge Amount", value: Bindable(stateManager).nudgeAmount, in: 1...20) I have to use Bindable(stateManager) rather than $stateManager as the $stateManager doesn't know its been unwrapped All of this works fine until I close a document, at which point I get a crash with the message "SwiftData/BackingData.swift:124: Fatal error: Unable to get value - no backing Managed Object" which appears to happen when trying to access some of the properties of my persistantStore object (which has been retired) I assume that my persistantStore object being an optional is part of the problem but I can't work out a better method of doing what I am trying to do
2
0
177
1h
SwiftData UndoManager leaks?
In any SwiftData project with undo enabled, I noticed that repeatedly undoing and redoing a change will cause memory to continuously climb. The larger the change, the more memory is consumed. This is surprising to me. I confirmed this on iOS and macOS using Xcode 15.4 and 16 beta. To reproduce, simply add undo/redo functionality to any project and repeatedly undo/redo a change. Memory consumption will climb continuously and will not get released. In Paul Hudson's SwiftData tutorials, he has an entire section about the numerous tricks required to get SwiftData relationships to work correctly. Does anyone know if SwiftData also requires tricks to get the UndoManager to work correctly?
1
0
55
10h
Core Data error: SQLITE_IOERR_SHMOPEN; what is this?
Hi, when setting up our Core Data stack in our iOS app (manually, with a NSManagedObjectModel/Context & NSPersistentStoreCoordinator) we have reports a rare bug we haven't been able to reproduce. Occasionally when adding a persistent store we get a NSCocoaErrorDomain 256 error (NSFileReadUnknownError) with NSSQLiteErrorDomain=4618 in the user info. That's SQLITE_IOERR_SHMOPEN , which the SQLite docs describe this way: I/O error within the xShmMap method on the sqlite3_io_methods object while trying to open a new shared memory segment It seems to specifically /not/ be a SQLITE_FULL error. Do you know what type of issue can cause this? Or where/how I can start tracking this down?
1
0
75
10h
SwiftData inside Actor leads to memory leaks
i am developing a SwiftUI App, where i need to work with relatively large amounts of data sets. While processing these data i had some issues with my app crashing randomly. As i was debugging this situation for a while i found out that dataraces were the cause for these crashes. That is why i decided to use an actor for these things.. As the actor takes care of concurrent threads, i was not having any crashes anymore, BUT, now i have to deal with some memory leaks! i've created a simple demo project to reproduce these leaks. my view: struct ContentView: View { @Environment(\.modelContext) private var modelContext // @Query private var items: [Item] var body: some View { VStack { Button(action: { Task { await testImport() } }, label: { Text("Import") }) } } } the function: func testImport() async { let actorX = testActor(container: self.modelContext.container) await actorX.cleanUp() // create dummy data: var dummyArray: [Int] = [] for i in 0...1300 { dummyArray.append(i) } await actorX.saveAssets(with: dummyArray) dummyArray = [] print("Checkpoint") } the actor: actor testActor { public var modelContainer: ModelContainer public var modelExecutor: any ModelExecutor private var context: ModelContext { modelExecutor.modelContext } public init(container: ModelContainer) { self.modelContainer = container let context = ModelContext(modelContainer) modelExecutor = DefaultSerialModelExecutor(modelContext: context) } func cleanUp() { print("starting cleanup...") do { try context.delete(model: Item.self) print("cleanup: table LocalAsset truncated") } catch { print("Failed to clear all LocalAsset data.") } } func saveAssets(with array: [Int]) { for i in 0..<array.count { let foo = array[i] let newItem = Item(timestamp: Date(), dummyInt: foo) context.insert(newItem) } try? context.save() } } And Here's a screenshot of Xcode's Instruments Leak tool: i hope somebody has any idea how to get rid of those leaks..
4
2
378
15h
SwiftData Custom Datastore Docs and Implementation
I have watched the following WWDC 2024 sessions: What’s new in SwiftData Create a custom data store with SwiftData Platform State of the Union Now, I have an application that exposes a GraphQL API endpoint that's using PostgreSQL Server 16.3 database. Next, this API returns JSON to the client application (i.e. SwiftUI app). Furthermore, I have checked the current documentation and the above videos appear to be the best reference at this time. My proposed architecture looks like the following: SwiftUI <--> SwiftData <--> PostgreStoreConfiguration && PostgreStore TBD <--> GraphQL API <--> PostgreSQL Thus, I have the following questions: Are there plans to add common out-of-the-box data store implementations for PostgreSQL, Cassandra, Redis, and so on? Will it be possible to implement data stores built to use gRPC, GraphQL, REST, and others to name a few? Will there be more documentation on the actual creation of a custom data store because the current documentation provides a slim API reference? I look forward to your feedback regarding the SwiftData custom data stores.
1
0
73
17h
SwiftData SchemaMigrationPlan and VersionedSchema not Sendable?
I've just tried to update a project that uses SwiftData to Swift 6 using Xcode 16 beta 1, and it's not working due to missing Sendable conformance on a couple of types (MigrationStage and Schema.Version): struct LocationsMigrationPlan: SchemaMigrationPlan { static let schemas: [VersionedSchema.Type] = [LocationsVersionedSchema.self] static let stages: [MigrationStage] = [] } struct LocationsVersionedSchema: VersionedSchema { static let models: [any PersistentModel.Type] = [ Location.self ] static let versionIdentifier = Schema.Version(1, 0, 0) } This code results in the following errors: error: static property 'stages' is not concurrency-safe because non-'Sendable' type '[MigrationStage]' may have shared mutable state static let stages: [MigrationStage] = [] ^ error: static property 'versionIdentifier' is not concurrency-safe because non-'Sendable' type 'Schema.Version' may have shared mutable state static let versionIdentifier = Schema.Version(1, 0, 0) ^ Am I missing something, or is this a bug in the current seed? I've filed this as FB13862584.
1
0
74
18h
SwiftData won't work with Measurement types
I'm trying out SwiftData and converting my existing data models using Structs and Codable to Classes and SwiftData. I've got a model that has a Measurement<UnitMass> type. When I run the app after converting everything to use classes with the @Model macro, I get a fatal error: SwiftData/SchemaProperty.swift:325: Fatal error: Unexpected type for CompositeAttribute: NSUnitMass. Since Measurement conforms to Codable, and SwiftData should work with Codable types, why is this not working? I also tried marking the property with @Attribute(.transformable) and it didn't make a difference.
10
11
2.6k
18h
SwiftData with shared and private containers
I was hoping for an update of SwiftData which adopted the use of shared and public CloudKit containers, in the same way it does for the private CloudKit container. So firstly, a big request to any Apple devs reading, for this to be a thing! Secondly, what would be a sensible way of adding a shared container in CloudKit to an existing app that is already using SwiftData? Would it be possible to use the new DataStore method to manage CloudKit syncing with a public or shared container?
2
0
113
1d
SwiftData Remote Database Updates
I just saw the new SwiftData updates, including the DataStore API. I’m wondering if, in the case of a shared remote datastore, it is possible to enable updates to the model context from the datastore without the model context explicitly requesting them (e.g., through database listeners). If I’m not mistaken, when you use CloudKit with SwiftData, this happens, right?
1
0
71
1d
SwiftData ModelContext Fetch Crashing
I'm currently using Xcode 16 Beta (16A5171c) and I'm getting a crash whenever I attempt to fetch using my ModelContext in my SwiftUI video using the environment I'm getting a crash specifically on iOS 18 simulators. I've opened up a feedback FB13831520 but it's worth noting that I can run the code I'll explain in detail below on iOS 17+ simulator and devices just fine. I'm getting the following crash: *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'The specified URI is not a valid Core Data URI: x-coredata:///MyApp/XXXXX-XXXXX-XXXX-XXXX-XXXXXXXXXXXX' It's almost as if on iOS18 SwiftData is unable to find the file on the simulator to perform CRUD operations. All I'm doing in my project is simply fetching data using the modelContext. func contains(_ model: MyModel, in context: ModelContext) -> Bool { let objId = palette.persistentModelID let fetchDesc = FetchDescriptor<MyModel>(predicate: #Predicate { $0.persistentModelID == objId }) let itemCount = try? context.fetchCount(fetchDesc) return itemCount != 0 }
2
1
113
1d
Access SwiftData in Widgets
How do I access the SwiftData ModelContainer of my app inside the widget extension? Following the guide to add a Widget Extension I’ve added the necessary target to my project and enabled App Groups. I’ve seen that the Backyard Birds example code offers an example how to build this, but it encapsulates the SwiftData handling in a separate app package. Therefore the example simply points to the app package. Though, in my case I don’t host my SwiftData in an external app package, but simply inside the regular app target. So, my question is how and at which point in code do I need to access the ModelContainer?
1
1
88
1d
Using Cloud Storage With SwiftData Custom Data Store
The following videos from WWDC24 say that we can use cloud storage for our SwiftData stores. Video references below: What's new in SwiftData Create a custom data store with SwiftData When watching the videos it shows examples of how we can read and write to a JSON file as a store, rather than using the built in store that comes with SwiftData. But there are mentions that we can use cloud storage like a backend i.e. a database hosted on a server. The only thing that I'm struggling to figure out and it would be great if we had code samples for this is how to achieve using cloud storage as a store since looking at the current implementations of: DataStoreConfiguration DataStore The required functions we need to implement look synchronous rather than asynchronous so how would or could we handle fetching asynchronous data from cloud storage. So how would we handle this? Also it would be great if someone could clarify how or if there is a way to send notifications for changes to your store between different devices similar to CloudKit? Are there there any plans to provide more documentation & sample code for the questions I've asked above? Feedback FB13857743
1
3
108
2d
SwiftData context disregards unique attribute
I have a simple model with a unique field. @Model class M { @Attribute(.unique) var value: String var date: Date var answer: Int init(value: String, date: Date = .now, answer: Int = 0) { self.value = value self.date = date self.answer = answer } } I am creating new objects with let x = M(value: "x") modelContext.insert(x) The value field has a unique constraint, and I am observing these differences in iOS 18 beta (Xcode 16.0 beta) from iOS 17.5 (Xcode 15.4): Multiple objects with the same value field appear in the list. If explicit modelContext.save() is called, list is not updated with latest values. Is this something I need to adjust to, or beta issues? Full source code: https://github.com/paiv/swiftdata-insert-unique-1
2
0
87
2d
Swift Chart causing app to crash when deleting an item from the data array
When deleting the last added item from a list view in my app a bar chart in a different view crashes my app. If I delete any other item in the list view everything work as expected. I'm using SwiftData in my app. Does anyone have any idea how I can prevent the app from crashing? I filter the data in the init to only have the current days data Chart View struct ConsumedDrinkChartView: View { @Environment(\.modelContext) var modelContext let screenVerticalSizeClass = UIScreen.VerticalSizeClass var compactScreen: Bool { return screenVerticalSizeClass == "compact" } @State private var chartCalendarUnit: Calendar.Component = .hour @State private var chartRange: ClosedRange<Date> @State private var axisValueLabelFormat: Date.FormatStyle @State private var axisValueLabelCount: Int @State private var startDate: Date @State private var endDate: Date @State private var plotStartPadding: Double = 0 @State private var plotEndPadding: Double = 0 @Binding var selectedTimeFrame:String @Query var consumedFluids: [ConsumedDrink] let defaultVolume = DataStore.defaultVolume init(selectedTimeFrame: Binding<String>, dateRange: ClosedRange<Date>) { _selectedTimeFrame = selectedTimeFrame _startDate = State(initialValue: Date().startOfDay) _endDate = State(initialValue: Date().endOfDay) let endDate = dateRange.upperBound let startDate = dateRange.lowerBound _consumedFluids = Query(filter: #Predicate { $0.date > startDate && $0.date < endDate }, sort: \ConsumedDrink.date) _chartRange = State(initialValue: dateRange) _axisValueLabelFormat = State(initialValue: .dateTime.hour(.conversationalDefaultDigits(amPM: .narrow))) _axisValueLabelCount = State(initialValue: 2) } var body: some View { Chart { ForEach(consumedFluids) { consumedFluid in BarMark(x: .value("Date", consumedFluid.date, unit: chartCalendarUnit), y: .value("Fluid Ounces", consumedFluid.drink.amount)) } .foregroundStyle(.pink) } .frame(height: 180) .padding() .chartXAxis { AxisMarks(values: .stride(by: chartCalendarUnit, count: axisValueLabelCount,roundLowerBound: true, roundUpperBound: true)) { _ in AxisGridLine() AxisValueLabel(format: axisValueLabelFormat, centered: true) } } .chartXScale(domain: chartRange, range: .plotDimension(startPadding: plotStartPadding, endPadding: plotEndPadding)) .background(RoundedRectangle(cornerRadius: 12).fill(Color(.secondarySystemBackground))) .onChange(of: selectedTimeFrame) { selectChartRange() } .onChange(of: consumedFluids) { print("consumedFluids: \(consumedFluids.count)") } .onAppear { selectChartRange() } } func selectChartRange() { plotStartPadding = 0 plotEndPadding = 0 switch selectedTimeFrame { case "Day": startDate = Date().startOfDay endDate = Date().endOfDay chartCalendarUnit = .hour axisValueLabelCount = 2 axisValueLabelFormat = .dateTime.hour(.conversationalDefaultDigits(amPM: .narrow)) case "Week": startDate = Date().add(days: -7) chartCalendarUnit = .day axisValueLabelCount = 1 axisValueLabelFormat = .dateTime.weekday() case "Month": startDate = Date().add(days: -30) chartCalendarUnit = .day axisValueLabelCount = 2 axisValueLabelFormat = .dateTime.day() plotStartPadding = 10 plotEndPadding = 10 case "SixMonths": let endOfMonth = Date().endOfMonth() startDate = endOfMonth.add(months: -6) chartCalendarUnit = .month axisValueLabelCount = 1 axisValueLabelFormat = .dateTime.month() plotStartPadding = 10 plotEndPadding = 32 case "Year": let endOfMonth = Date().endOfMonth() startDate = endOfMonth.add(months: -12) chartCalendarUnit = .month axisValueLabelCount = 1 axisValueLabelFormat = .dateTime.month(.narrow) plotStartPadding = 15 plotEndPadding = 15 default: chartCalendarUnit = .day } chartRange = startDate...endDate } } List View struct ConsumedDrinkListView: View { @Environment(\.modelContext) var modelContext @Query(sort: \ConsumedDrink.date) var dailyConsumedFluids: [ConsumedDrink] @State private var showingAlert = false @State private var alertMessage: String = "" @State private var alertTitle: String = "" var body: some View { NavigationStack { if dailyConsumedFluids.isEmpty { ContentUnavailableView("No Consumed Drinks", systemImage: "mug.fill", description: Text("Drink some water and stay hydrated.")) } else { List { ForEach(dailyConsumedFluids, id: \.self) { consumedDrink in NavigationLink { EditConsumedDrinkView(consumedDrink: consumedDrink) } label: { ConsumedDrinkRowView(consumedDrink: consumedDrink) } .swipeActions{ Button("Delete", systemImage: "trash", role: .destructive) { deleteConsumedDrink(consumedDrink: consumedDrink) } .tint(.red) } } } .listStyle(.plain) .alert(isPresented: $showingAlert) { Alert(title: Text(alertTitle), message: Text(alertMessage), dismissButton: .default(Text("OK")) ) } } Text("") .navigationTitle("Consumed Drinks") .navigationBarTitleDisplayMode(.inline) } } func deleteConsumedDrink(consumedDrink: ConsumedDrink) { do { if modelContext.hasChanges { print("ConsumedDrinkListView.deleteConsumedDrink") print("modelContext has Changes. Saving modelContext") try modelContext.save() } try DataStore.deleteConsumedDrink(drink: consumedDrink, modelContext: modelContext) } catch { self.alertTitle = "Error deleting consumed drink - \(consumedDrink.drink.name)" self.alertMessage = error.localizedDescription self.showingAlert = true } } }
1
0
112
2d