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.

SwiftData Documentation

Posts under SwiftData tag

218 Posts
Sort by:
Post not yet marked as solved
0 Replies
29 Views
There is something that I'm spending hours trying to solve but start to be blocked. On one of my app projects, I'm experiencing random fatal errors during the access and update of SwiftData Models, which does not occur when using CoreData. This mainly happens when setting value for newly created entities: SwiftData randomly crashes the application with the following error: EXC_BAD_ACCESS (code=1, address=0x11). I made sure to update the code to move operations in the background and to use a ModelActor. It works properly, but 1 out of 3 times, it crashes with the error quoted. I also tried to look at previous posts and made sure to persist the context when creating new entities, before updating them. The last information in my console before “(lldb)” is: CoreData: debug: CoreData+CloudKit: -[NSCloudKitMirroringDelegate managedObjectContextSaved:](2996): <NSCloudKitMirroringDelegate: 0x2806342a0>: Observed context save: <NSPersistentStoreCoordinator: 0x281434c40> - <NSManagedObjectContext: 0x280450820> CoreData: debug: CoreData+CloudKit: -[NSCloudKitMirroringDelegate remoteStoreDidChange:](3039): <NSCloudKitMirroringDelegate: 0x2806342a0>: Observed remote store notification: <NSPersistentStoreCoordinator: 0x281434c40> - FF2D0015-7121-4C30-9EE3-2A51A76C303B - <NSPersistentHistoryToken - { "FF2D0015-7121-4C30-9EE3-2A51A76C303B" = 1316; }> - file:///private/var/mobile/Containers/Shared/AppGroup/ED0B229A-F5BC-47B7-B7BC-88EEFB6E6CA8/Library/Application%20Support/default.store CoreData: debug: CoreData+CloudKit: -[NSCloudKitMirroringDelegate managedObjectContextSaved:](2996): <NSCloudKitMirroringDelegate: 0x2806342a0>: Observed context save: <NSPersistentStoreCoordinator: 0x281434c40> - <NSManagedObjectContext: 0x280450820>. In the rare occasion where it provides more details, Xcode shows issue in the @Model macro, as shown in the screenshot attached. I was able to reproduce this issue on 4 different physical devices and in the simulator. It also happens, less frequently, when trying to fetch a Model entity from the SwiftData context. Not for specific models tho, it can happen for all of them, randomly. I was able to experience this random problem both on iOS 17.0 Developer Beta, RC & the official iOS 17.0 release. At the time in the beta Xcode 15, and now the latest stable Xcode. Am I the only one having this kind of issues? Or is it a known issue with Swift? Anybody has idea how I could solve that?
Posted
by hiwelo.
Last updated
.
Post not yet marked as solved
7 Replies
436 Views
In Xcode Version 15.0 beta (15A5160n) this predicate will not build: let thisPredicate = #Predicate<Ledgers> { ($0.myStore != nil) } The definition of .myStore in the Ledgers class is: var myStore: Stores? an optional relationship. Is there anyway to test for nil optional relationships in SwiftData? The inverse relationship in Stores is: @Relationship(.deny, inverse: \Ledgers.myStore) var myReceipts: [Ledgers]
Posted
by adamek.
Last updated
.
Post not yet marked as solved
2 Replies
261 Views
Hi, say in my model I have members and each member optionally can have a relationship to a Club. So the relationship in the Member entity would be modelled like so: @Relationship(.nullify, inverse: \Club.members) var club: Club? Now I would like to fetch al Members with no Club relationship. I would assume that this would work with a predicate like this: let noClubPred = #Predicate<Member> { member in member.club == nil } Unfortunately this gives me the following error when compiling: Generic parameter 'RHS' could not be inferred. Has anybody an idea how to phrase this predicate correctly, or is this a beta issue and it should actually work? Thank you! Cheers, Michael
Posted
by milutz.
Last updated
.
Post not yet marked as solved
1 Replies
42 Views
Like the title says, I've realised that when I try to use filter or sort on properties that aren't standard supported data types i.e. Using a transformable or a value type like an enum, I seem to be getting the following crash... SwiftData/DataUtilities.swift:1140: Fatal error: Unexpected type for Expansion: Optional<UIColor> Xcode expands and shows me when trying to access the wrapped value it's crashing. I'm assumung that the query property wrapper can't handle these custom data types @Query private var items: [Item] { get { _items.wrappedValue <--- Crash here } } Which seems to be pointing to a transferable property in one of my models. Below are my two models i'm using. enum Priority: Int, Codable, Identifiable, CaseIterable { case low case medium case high var title: String { switch self { case .low: return "Low" case .medium: return "Medium" case .high: return "High" } } var image: Image? { switch self { case .medium: return Image(systemName: "exclamationmark.2") case .high: return Image(systemName: "exclamationmark.3") default: return nil } } var id: Self { self } } @Model final class Item: Codable { var title: String @Attribute(originalName: "timestamp") var dueDate: Date var isCompleted: Bool var isFlagged: Bool = false var isArchived: Bool = false var isCritical: Bool? var priority: Priority? @Relationship(deleteRule: .nullify, inverse: \Category.items) var category: Category? @Attribute(.externalStorage) var image: Data? enum CodingKeys: String, CodingKey { case title case timestamp case isCritical case isCompleted case category case imageName } init(title: String = "", dueDate: Date = .now, priority: Priority? = nil, isCompleted: Bool = false) { self.title = title self.dueDate = dueDate self.priority = priority self.isCompleted = isCompleted } init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) self.title = try container.decode(String.self, forKey: .title) self.dueDate = Date.randomDateNextWeek() ?? .now self.isCompleted = try container.decode(Bool.self, forKey: .isCompleted) self.category = try container.decodeIfPresent(Category.self, forKey: .category) if let imageName = try container.decodeIfPresent(String.self, forKey: .imageName), let imageData = UIImage(named: imageName) { self.image = imageData.jpegData(compressionQuality: 0.8) } if let isCritical = try container.decodeIfPresent(Bool.self, forKey: .isCritical), isCritical == true { self.priority = .high } } func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(title, forKey: .title) try container.encode(dueDate, forKey: .timestamp) try container.encode(isCompleted, forKey: .isCompleted) try container.encode(category, forKey: .category) } } @Model class Category: Codable { @Attribute(.unique) var title: String var items: [Item]? @Attribute(.transformable(by: ColorValueTransformer.self)) var color: UIColor? init(title: String = "", color: UIColor) { self.title = title self.color = color } enum CodingKeys: String, CodingKey { case title } required init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) self.title = try container.decode(String.self, forKey: .title) self.color = UIColor(possibleColors.randomElement()!) } func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(title, forKey: .title) } } And below is an example of me sorting based on my enum (Priority) & Relationship (Category name) func sort() -> [SortDescriptor<Item>]{ switch self { case .title: [SortDescriptor(\Item.title)] case .date: [SortDescriptor(\Item.dueDate)] case .category: [SortDescriptor(\Item.category?.title)] case .priority: [SortDescriptor(\Item.priority?.rawValue)] } } And a filter example below creating a predicate that we will execute to return and matches found in the title or category title let highPriority = Priority.high if let query { return #Predicate { $0.priority == highPriority && ($0.title.contains(query) || $0.category?.title.contains(query) == true) && $0.isArchived == false } } I'm pretty sure this is a SwiftData bug since when using strings, bools and dates it's all fine using anything outside of that box causes these crashes...
Posted
by tundsdev.
Last updated
.
Post not yet marked as solved
0 Replies
43 Views
I have two models: @Model class User: Codable { @Attribute(.unique) var username: String @Attribute(.unique) var email: String var firstName: String var lastName: String @Attribute(.unique) var id: Int @Relationship(inverse: \House.members) var houses: [House] = [] init(username: String, email: String, firstName: String, lastName: String, id: Int) { self.username = username self.email = email self.firstName = firstName self.lastName = lastName self.id = id } enum CodingKeys: String, CodingKey { case username case email case firstName = "first_name" case lastName = "last_name" case id } required init(from decoder: Decoder) throws { ... } func encode(to encoder: Encoder) throws { ... } } and @Model class House: Codable { var name: String var city: String var address: String @Attribute(.unique) var id: Int var ownerID: Int var members: [User] init(name: String, city: String, address: String, id: Int, ownerID: Int, members: [User]) { self.name = name self.city = city self.address = address self.id = id self.ownerID = ownerID self.members = members } enum CodingKeys: String, CodingKey { case name case city case address case id case ownerID = "owner_id" case members } required init(from decoder: Decoder) throws { ... } func encode(to encoder: Encoder) throws { ... } } I want to save a list of House objects I receive in JSON format: [ { "name": "A", "city": "A", "address": "A", "id": 1, "owner_id": 1, "members": [ { "username": "A", "email": "A", "first_name": "A", "last_name": "A", "id": 1 } ] } ... ] This is the code I use: import SwiftUI import SwiftData struct HouseListView: View { @Environment(\.modelContext) var modelContext @Query(sort: \House.name) var houses: [House] var body: some View { NavigationStack { List { ForEach(houses) { house in Text(house.name) } } .task { if let houses = await getHouses() { do { for house in houses { modelContext.insert(house) } try modelContext.save() } catch { print(error) } } } } } } But I receive the following errors: Error Domain=NSCocoaErrorDomain Code=1560 "Multiple validation errors occurred." UserInfo={NSDetailedErrors=( "Error Domain=NSCocoaErrorDomain Code=1570 \"%{PROPERTY}@ is a required value.\" UserInfo={NSValidationErrorObject=<NSManagedObject: 0x2827cc8c0> (entity: User; id: 0x2804967e0 <x-coredata:///User/tAC4F0253-65B0-4C92-846F-8E72A8E115277>; data: {\n email = nil;\n firstName = nil;\n houses = (\n );\n id = nil;\n lastName = nil;\n username = nil;\n}), NSLocalizedDescription=%{PROPERTY}@ is a required value., NSValidationErrorKey=email, NSValidationErrorValue=null}", "Error Domain=NSCocoaErrorDomain Code=1570 \"%{PROPERTY}@ is a required value.\" UserInfo={NSValidationErrorObject=<NSManagedObject: 0x2827cc8c0> (entity: User; id: 0x2804967e0 <x-coredata:///User/tAC4F0253-65B0-4C92-846F-8E72A8E115277>; data: {\n email = nil;\n firstName = nil;\n houses = (\n );\n id = nil;\n lastName = nil;\n username = nil;\n}), NSLocalizedDescription=%{PROPERTY}@ is a required value., NSValidationErrorKey=firstName, NSValidationErrorValue=null}", "Error Domain=NSCocoaErrorDomain Code=1570 \"%{PROPERTY}@ is a required value.\" UserInfo={NSValidationErrorObject=<NSManagedObject: 0x2827cc8c0> (entity: User; id: 0x2804967e0 <x-coredata:///User/tAC4F0253-65B0-4C92-846F-8E72A8E115277>; data: {\n email = nil;\n firstName = nil;\n houses = (\n );\n id = nil;\n lastName = nil;\n username = nil;\n}), NSLocalizedDescription=%{PROPERTY}@ is a required value., NSValidationErrorKey=id, NSValidationErrorValue=null}", "Error Domain=NSCocoaErrorDomain Code=1570 \"%{PROPERTY}@ is a required value.\" UserInfo={NSValidationErrorObject=<NSManagedObject: 0x2827cc8c0> (entity: User; id: 0x2804967e0 <x-coredata:///User/tAC4F0253-65B0-4C92-846F-8E72A8E115277>; data: {\n email = nil;\n firstName = nil;\n houses = (\n );\n id = nil;\n lastName = nil;\n username = nil;\n}), NSLocalizedDescription=%{PROPERTY}@ is a required value., NSValidationErrorKey=lastName, NSValidationErrorValue=null}", "Error Domain=NSCocoaErrorDomain Code=1570 \"%{PROPERTY}@ is a required value.\" UserInfo={NSValidationErrorObject=<NSManagedObject: 0x2827cc8c0> (entity: User; id: 0x2804967e0 <x-coredata:///User/tAC4F0253-65B0-4C92-846F-8E72A8E115277>; data: {\n email = nil;\n firstName = nil;\n houses = (\n );\n id = nil;\n lastName = nil;\n username = nil;\n}), NSLocalizedDescription=%{PROPERTY}@ is a required value., NSValidationErrorKey=username, NSValidationErrorValue=null}", "Error Domain=NSCocoaErrorDomain Code=1570 \"%{PROPERTY}@ is a required value.\" UserInfo={NSValidationErrorObject=<NSManagedObject: 0x2827cca00> (entity: User; id: 0x280496a80 <x-coredata:///User/tAC4F0253-65B0-4C92-846F-8E72A8E115279>; data: {\n email = nil;\n firstName = nil;\n houses = (\n );\n id = nil;\n lastName = nil;\n username = nil;\n}), NSLocalizedDescription=%{PROPERTY}@ is a required value., NSValidationErrorKey=email, NSValidationErrorValue=null}", "Error Domain=NSCocoaErrorDomain Code=1570 \"%{PROPERTY}@ is a required value.\" UserInfo={NSValidationErrorObject=<NSManagedObject: 0x2827cca00> (entity: User; id: 0x280496a80 <x-coredata:///User/tAC4F0253-65B0-4C92-846F- ..... )} ForEach<Array<House>, Int, Text>: the ID 3 occurs multiple times within the collection, this will give undefined results!
Posted Last updated
.
Post not yet marked as solved
6 Replies
738 Views
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.
Posted
by jonduenas.
Last updated
.
Post not yet marked as solved
2 Replies
695 Views
Consider the Categories class below. Without the @Model line, Xcode has no problems. As soon as the @Model line is added, Xcode protests that the class does not conform to Decodable or Encodable. Apparently the @Model macro expanded macro prevents the implied boilerplate that the systems adds when the Codable protocol is added to the class. I've filed feedback (FB12444837) for this. Does anyone have suggestions that will let me avoid the boilerplate? This is the simplest class in my schema, I've got 12 other classes with many more variables. @Model class Categories: Identifiable, Codable { // MARK: Identifiable var id: UUID { return uuidKey } // MARK: - Properties @Attribute(.unique) var uuidKey: UUID = UUID() var dateCreated: Date = Date() var dateModified: Date = Date() var dateRealm: Date? = nil var uuidUser: UUID = UUID() var uuidFamily: UUID = UUID() var myName: String = "" }
Posted
by adamek.
Last updated
.
Post not yet marked as solved
2 Replies
82 Views
Problem The following code doesn't work: let predicate = #Predicate<Car> { car in car.size == size //This doesn't work } Console Error Query encountered an error: SwiftData.SwiftDataError(_error: SwiftData.SwiftDataError._Error.unsupportedPredicate) Root cause Size is an enum, #Predicate works with other type such as String however doesn't work with enum Enum value is saved however is not filtered by #Predicate Environment Xcode: 15.0 (15A240d) - App Store macOS: 14.0 (23A339) - Release Candidate Steps to reproduce Run the app on iOS 17 or macOS Sonoma Press the Add button Notice that the list remains empty Expected behaviour List should show the newly created small car Actual behaviour List remains empty inspite of successfully creating the small car. Feedback FB13194334 Code Size enum Size: String, Codable { case small case medium case large } Car import SwiftData @Model class Car { let id: UUID let name: String let size: Size init( id: UUID, name: String, size: Size ) { self.id = id self.name = name self.size = size } } ContentView struct ContentView: View { var body: some View { NavigationStack { CarList(size: .small) } } CarList import SwiftUI import SwiftData struct CarList: View { let size: Size @Environment(\.modelContext) private var modelContext @Query private var cars: [Car] init(size: Size) { self.size = size let predicate = #Predicate<Car> { car in car.size == size //This doesn't work } _cars = Query(filter: predicate, sort: \.name) } var body: some View { List(cars) { car in VStack(alignment: .leading) { Text(car.name) Text("\(car.size.rawValue)") Text(car.id.uuidString) .font(.footnote) } } .toolbar { Button("Add") { createCar() } } } private func createCar() { let name = "aaa" let car = Car( id: UUID(), name: name, size: size ) modelContext.insert(car) } }
Posted
by newwbee.
Last updated
.
Post not yet marked as solved
1 Replies
46 Views
Sorry for the rudimentary question, SwiftData question.
In the case of Xcode standard sample code, @main struct SwiftDataTestProjectsApp: App { var sharedModelContainer: ModelContainer = { let schema = Schema([ Department.self,. ]) let modelConfiguration = ModelConfiguration(schema: schema, isStoredInMemoryOnly: false) do { return try ModelContainer(for: schema, configurations: [modelConfiguration]) } catch { fatalError("Could not create ModelContainer: \(error)") } }() var body: some Scene { WindowGroup { ContentView() } .modelContainer(sharedModelContainer) } } and create a ModelContainer for the Scene, #Preview { ContentView() .modelContainer(for: Item.self, inMemory: true) } However, if SwiftData is not used in the ContentView, and only if the transition is made to the other view using NavigationLink, as shown in the code below, a ModelContainer is created and a ModelContainer is specified for the ContentTwoView, If I want to specify a separate container for ContentTwoView, how should I create .modelContainer(sharedModelContainer) and specify .modelContainer(for: Item.self, inMemory: true)? Should I continue to create the ModelContainer for the Scene as before? Or is there a way to create it only for the specified View and specify it there? struct ContentView: View { var body: some View { NavigationStack { NavigationLink("ContentTwoView") { ContentTwoView()) } } } } struct ContentTwoView: View { @Environment(\.modelContext) private var modelContext @Query private var items: [Item]. var body: some View {
Posted
by X001017.
Last updated
.
Post marked as solved
3 Replies
62 Views
I've been stuck on this one for quite a while now, and I'm starting to become more and more convinced this is an issue with Xcode 15 Beta RC. Just to give you some context I seem to be getting the following crash after modifying my schema (adding new properties) for the the second time. Below is the crash that is occurring on my device & simulator. Unresolved error loading container Error Domain=NSCocoaErrorDomain Code=134130 "Persistent store migration failed, missing source managed object model." UserInfo={URL=file:///Users/xxxxx/Library/Developer/CoreSimulator/Devices/23B8CDDD-CC5F-4A1C-B0F4-CF89C77B7ECF/data/Containers/Data/Application/235A14D7-6492-439F-BB4D-B18498D80970/Library/Application%20Support/default.store, metadata={ NSPersistenceFrameworkVersion = 1327; NSStoreModelVersionChecksumKey = "dia3s8Q2+lqw669j9+RcPLQ+06yu0x6BBTZ4cXoQ1os="; NSStoreModelVersionHashes = { Category = {length = 32, bytes = 0x187754bb 36c51a62 85ede16f 4b2a3912 ... 57326030 2de7ef77 }; Item = {length = 32, bytes = 0xa7e4be4d ddd86d36 f71799b0 bc69dcb4 ... 83d47dfe d433fc01 }; }; NSStoreModelVersionHashesDigest = "G/Tk4lzyeNBXzf5+7qxbd+isF8uFnSaC5LtUCCkC8GQwaG1d9Di0eJ10NQEyPgwRczoYeYAMYG8ai4RooEhH9w=="; NSStoreModelVersionHashesVersion = 3; NSStoreModelVersionIdentifiers = ( "1.2.0" ); NSStoreType = SQLite; NSStoreUUID = "A99894EA-FA7B-4CA7-AEB7-6DEE42843EC0"; "_NSAutoVacuumLevel" = 2; }, reason=Can't find model for source store} I currently have 5 versions of my Schemas there's two of them Item Category Below is a minified changelog of what has changed between versions. Version 1 (Initial Version) Version 2 (Lightweight Migration - Property is renamed in Item) Version 3 (Custom Migration - New Property is added to Item both are bools) Version 4 (Custom Migration - New Property is added to Category which is a transformable) Version 5 (Custom Migration - New Property is added to Item which is a string) It's quite a large file with all of the version schema's etc so i've created a gist here for you to see all of the changes that have been made between Version 1 up until Version 5. The problem that I'm seeing is that between migration for V1 up until V4 everything is fine. It's only until SwiftData attempt to migrate V4 to V5 and I get the crash that I have provided above, and V5 only has a new string property which shouldn't be causing a crash since I've done 2 custom migrations that were all fine before V5 so this seems really strange even tho my migration plan is setup properly which you can see below. enum ToDosMigrationPlan: SchemaMigrationPlan { static var schemas: [VersionedSchema.Type] { [ToDosSchemaV1.self, ToDosSchemaV2.self, ToDosSchemaV3.self, ToDosSchemaV4.self, ToDosSchemaV5.self] } static var stages: [MigrationStage] { [ migrateV1toV2, migrateV2toV3, migrateV3toV4, migrateV4toV5 ] } // V1 to V2 static let migrateV1toV2 = MigrationStage.lightweight( fromVersion: ToDosSchemaV1.self, toVersion: ToDosSchemaV2.self ) // V2 to V3 static let migrateV2toV3 = MigrationStage.custom( fromVersion: ToDosSchemaV2.self, toVersion: ToDosSchemaV3.self, willMigrate: nil, didMigrate: { context in let items = try? context.fetch(FetchDescriptor<ToDosSchemaV3.Item>()) items?.forEach { item in item.isFlagged = false item.isArchived = false } try? context.save() }) static let migrateV3toV4 = MigrationStage.custom( fromVersion: ToDosSchemaV3.self, toVersion: ToDosSchemaV4.self, willMigrate: nil, didMigrate: { context in let categories = try? context.fetch(FetchDescriptor<ToDosSchemaV4.Category>()) categories?.forEach { category in category.color = UIColor(possibleColors.randomElement()!) } try? context.save() }) static let migrateV4toV5 = MigrationStage.custom( fromVersion: ToDosSchemaV4.self, toVersion: ToDosSchemaV5.self, willMigrate: nil, didMigrate: { context in // TODO: Handle setting some custom data here with defaults }) } Has anyone come across this or got any ideas as to what the problem may be?
Posted
by tundsdev.
Last updated
.
Post not yet marked as solved
3 Replies
375 Views
I am using SwiftData for my model. Until Xcode 15 beta 4 I did not have issues. Since beta 5 I am receiving the following red warning multiple times: 'NSKeyedUnarchiveFromData' should not be used to for un-archiving and will be removed in a future release This seems to be a CoreData warning. However, I am not using CoreData directly. I have no way to change the config of CoreData as used by SwiftData. My model just uses UUID, Int, String, Double, some of them as optionals or Arrays. I only use one attribute (.unique).
Posted Last updated
.
Post not yet marked as solved
0 Replies
59 Views
I have a Model Class Note: @Model class Note { var id: UUID var created: Date var content: String @Relationship(inverse: \Event.notes) var events: [Event]? init(_ content: String, created: Date = .now, events: [Event] = []) { self.id = UUID() self.created = created self.content = content self.events = events } } And Event: @Model class Event: Hashable, Equatable { var id: String var name: String var eventNotes: String? @Relationship var notes: [Note]? // @Transient does not publish (iOS bug?), use .ephemeral instead @Attribute(.ephemeral) var isSelected: Bool = false init(_ name: String = "Unnamed Event", calendarId: String, eventNotes: String) { self.id = calendarId self.name = name self.eventNotes = eventNotes } init(from calendarEvent: EKEvent) { self.id = calendarEvent.eventIdentifier self.name = calendarEvent.title self.eventNotes = calendarEvent.notes ?? "" } ... static func loadEvents(date: Date = Date()) -> [Event] { ... } } I have the following View hierarchy NoteInputView which has @State var events: [Event] = [] SelectEventButton which has @Binding var events: [Event] and calls Event.loadEvent() to retrieve list of events SelectEventSheet which has @Binding var events: [Event] and lets the user toggle isSelected GitHub Gist with all relevant files Adding notes with same events crashes... With this setup, I attempt so save new notes in NoteInputView by calling addNote: func addNote() -> Note { let selectedEvents = events.filter({ $0.isSelected }) let note = Note(newNoteContent, events: selectedEvents) context.insert(note) do { try context.save() } catch { print(error) } return note } This works for the first note after opening the app, or if every subsequent note has a different event selected. However, storing a second note with the same event crashes with the following error: "Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Illegal attempt to establish a relationship 'events' between objects in different contexts" (complete error see here) The error occurs at context.insert, which doesn't throw. If I force quit the app, and then add a note with the same events as an already persisted note, no error is thrown (until a I add another note with the same event without force-quitting). ... but not because one cannot refer to the same events twice It's not a problem of referring to the same events, as the following code also works fine for multiple notes: func addNote() -> Note { // This works, despite notes also always referring to the same events let note = Note(newNoteContent, events: Event.loadEvents()) context.insert(note) do { try context.save() } catch { print(error) } return note } . ... workaround? Manually adding events to the context before adding it to the notes One workaround seems to be to add the events to the context before adding the note: func addNote() -> Note { let selectedEvents = events.filter({ $0.isSelected }) selectedEvents.forEach({context.insert($0)}) let note = Note(newNoteContent, events: events) context.insert(note) do { try context.save() } catch { print(error) } return note } . ... but why? While this works, I cannot quite make sense of this. It seems that passing events around between views may be the culprit, or that loadEvents is called in a child view. Would love some advice, since this doesn't seem like intended behavior.
Posted
by henningko.
Last updated
.
Post not yet marked as solved
0 Replies
52 Views
I have a question regarding the following SwiftUI setup using @Model. I have a parent view which queries the model, extracts the first element, and passes that to child views. My issue is that when I make changes to properties marked as @Transient in the model, the child views do not re-render. Parent struct ParentView: View { @Query private var myData: [MyData] var body: some View { if let data = myData.first { TabView { Overview(data: data) Details(data: data) } .tabViewStyle(.verticalPage(transitionStyle: .identity)) } else { ContentUnavailableView { Label { Text(verbatim: "Failed to load app content") } icon: { Image(systemName: "xmark") } } } } } Child struct ChildView: View { var data: WaterData var body: some View { Text("\(data.progress)") } } If I query the model in the child view directly, then changes correctly propagate to the child view. What am I doing wrong? Is there a property with which I can mark the var data in the child view to let SwiftUI know it should observe changes? The underlying data in the model is marked @Transient because the source of truth is synched from Apple Health: @Transient public var samples: [HKQuantitySample] = [] I should also note that the child view renders based on computed properties, such as: public var progress: Double { let todaysRecords = samples.filter { Calendar.autoupdatingCurrent.isDateInToday($0.endDate) } let sum = todaysRecords.reduce(0, { sum, record in sum + record.quantity.doubleValue(for: .literUnit(with: .milli)) }) return sum } Apologies for the messy post. I'm not sure which part of this setup breaks the UI updates. I could imagine having a transient property and using computed vars in the UI prevent SwiftUI from knowing about the changes. On the other hand, if I do the @Query inside the child view, it works, despite the transient prop and computer vars.
Posted Last updated
.
Post not yet marked as solved
5 Replies
618 Views
When I update a variable inside my model that is marked @Transient, my view does not update with this change. Is this normal? If I update a non-transient variable inside the model at the same time that I update the transient one, then both changes are propagated to my view. Here is an example of the model: @Model public class WaterData { public var target: Double = 3000 @Transient public var samples: [HKQuantitySample] = [] } Updating samples only does not propagate to my view.
Posted Last updated
.
Post not yet marked as solved
1 Replies
102 Views
How do I reorder list item in Swift Data with the @Query request? I have a list pulling from Swift Data that I would like to make reorderable but it throws this error: "Cannot use mutating member on immutable value: 'locations' is a get-only property". Is it possible to reorder Swift Data items?
Posted Last updated
.
Post not yet marked as solved
4 Replies
1.3k Views
Hey, I am trying to save an enum in my model with SwiftData but getting a weird error message I do not understand at the moment, and I am pretty sure I am missing something here. public enum URLScheme: String, Codable { case https case http } @Model public class MyModel { public var urlScheme: URLScheme } When I try to save the model I get the following error message in the console: error: Row (pk = 1) for entity 'MyModel' is missing mandatory text data for property 'https' I was wondering if I need to tell SwiftData how to save my enum ? My assumption was that I can save any enum if it conforms to Codable. Am I doing something wrong here or is this a beta bug ? Thanks a lot for helping
Posted Last updated
.
Post not yet marked as solved
0 Replies
73 Views
I want to make an MacOS app with Swiftdata but there is a problem. When i create a new project and select swiftdata xcode provides example of swiftdata. When I launch the app on my Mac I get the following error in the console: dyld[61569]: Symbol not found: _$s9SwiftData6SchemaC16PropertyMetadataVMa Expected in: <A7F2CF0D-77A3-3F13-BE59-DCBAC4C53133> /System/Library/Frameworks/SwiftData.framework/Versions/A/SwiftData And this : dyld`: 0x7ff8190208a8 <+0>: movl $0x2000209, %eax ; imm = 0x2000209 0x7ff8190208ad <+5>: movq %rcx, %r10 0x7ff8190208b0 <+8>: syscall -> 0x7ff8190208b2 <+10>: jae 0x7ff8190208bc ; <+20> 0x7ff8190208b4 <+12>: movq %rax, %rdi 0x7ff8190208b7 <+15>: jmp 0x7ff818fb50db ; cerror_nocancel 0x7ff8190208bc <+20>: retq 0x7ff8190208bd <+21>: nop 0x7ff8190208be <+22>: nop 0x7ff8190208bf <+23>: nop with the following sentence : Thread 1: signal SIGABRT So my model code is : import Foundation import SwiftData @Model class Paint{ var id: UUID var name: String var heigt: Int var width: Int var category: String var year: String var price: Int var isSold: Bool init(name:String, heigt:Int, width: Int, category: String, year: String, price: Int, isSold : Bool){ self.id = UUID() self.name = name self.heigt = heigt self.width = width self.category = category self.year = year self.price = price self.isSold = isSold } } func addPaint(name:String, heigt:Int, width: Int, category: String, year: String, price: Int, isSold:Bool, context: ModelContext) { let newPaint = Paint(name: name, heigt: heigt, width: width, category: category, year: year, price: price, isSold: isSold) print("item save sucessfully") context.insert(newPaint) } The contentView : import SwiftUI import SwiftData struct ContentView: View { @Environment(\.modelContext) private var context var body: some View { VStack { Image(systemName: "globe") .imageScale(.large) .foregroundStyle(.tint) Text("Hello, world!") Button("add"){ addPaint(name: "test", heigt: 1, width: 1, category: "", year: "2023", price: 10, isSold: false, context: context) } } .padding() } } and finally the main : import SwiftUI import SwiftData @main struct syhomApp: App { var body: some Scene { WindowGroup { ContentView() } .modelContainer(for: Paint.self) } } please help me !! I have a solution : use CoreData instead but I really want to do it with SwiftData. The thing is and I create a SwiftData projet for iOS every thing is working well (why ?) ...
Posted
by 314.
Last updated
.
Post not yet marked as solved
1 Replies
112 Views
I'm following the Build an app with SwiftData from WWDC 2023. I'm using the Xcode release candidate for Xcode 15. i'm running the Developer Beta for Sonoma. The first change was to import SwiftData, add the @Model macro to the Definition for the Card object and remove @Published from two variable in the definition. After doing this I get 5 errors: External macro implementation type 'SwiftDataMacros.PersistentModelMacro' could not be found for macro 'Model()' The instructions continue to the CardEditorView and change the macro for var card to @Bindable with the error 'init(wrappedValue:)' is unavailable: The wrapped value must be an object that conforms to Observable Then we move to the App main class where we add .modelContainer(for: Card.self) and get the error No exact matches in call to instance method 'modelContainer' Any clue why this is happening?
Posted Last updated
.