Build an app with SwiftData

RSS for tag

Discuss the WWDC23 Build an app with SwiftData

View Session

Posts under wwdc2023-10154 tag

62 Posts
Sort by:
Post not yet marked as solved
3 Replies
1.3k Views
@Model class AModel { @Attribute(.unique) var id:String var date:Date var b:[BModel] init() { self.id = UUID().uuidString self.date = Date() self.b = [] } } @Model class BModel { @Attribute(.unique) var id:String var date:Date init() { self.id = UUID().uuidString self.date = Date() } } struct MainView: View { @Environment(\.modelContext) private var db @State private var a:AModel = AModel() var body: some View { VStack { } .onAppear { a.b.append(BModel()) print(a.b) } } } // CRASH : @Model class AModel { @Attribute(.unique) var id:String var date:Date var b:[BModel] /** Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0) { get { _$observationRegistrar.access(self, keyPath: \.b) return self.getValue(for: \.b) } set { _$observationRegistrar.withMutation(of: self, keyPath: \.b) { self.setValue(for: \.b, to: newValue) } } } */ init() { self.id = UUID().uuidString self.date = Date() self.b = [] } } @Model class BModel { @Attribute(.unique) var id:String var date:Date init() { self.id = UUID().uuidString self.date = Date() } }
Posted Last updated
.
Post marked as solved
1 Replies
728 Views
I'm converting my app to use SwiftData. I have a class called MergeRequest which everytime I insert it into the modelContext it fails with the following error: CoreData: error: CoreData: error: Row (pk = 1) for entity 'MergeRequest' is missing mandatory text data for property 'id' CoreData: error: CoreData: error: Row (pk = 2) for entity 'MergeRequest' is missing mandatory text data for property 'id' (... repeated for each inserted item) When I print the id before inserting the class does have a coredata generated id. PersistentIdentifier(id: SwiftData.PersistentIdentifier.ID(url: x-coredata:///MergeRequest/t5B3316FC-DBE0-4440-88E5-8EDFBA7E856A3), implementation: SwiftData.PersistentIdentifierImplementation) This is where I insert the model: https://github.com/StefKors/GitLab/blob/cb4c1ef6dec616d5ac146d712658496095c82243/Shared/UserInterface/UserInterface.swift#L137 And this is the full model class: https://github.com/StefKors/GitLab/blob/cb4c1ef6dec616d5ac146d712658496095c82243/Shared/UserInterface/SwiftData/MergeRequest.swift What I don't get is why does this error happen while it does have an id. Is there some debugging I can do to get more information?
Posted Last updated
.
Post not yet marked as solved
1 Replies
902 Views
The Sendable documentation says we can mark reference types as Sendable if they "internally manage access to their state." Adding Sendable conformance to my SwiftData classes silences warnings such as the following: "Non-sendable type '[Item]' returned by implicitly asynchronous call to nonisolated function cannot cross actor boundary" @Model final class Item: Sendable { var sampleProperty = "" } My understanding is that the compiler would complain if adding explicit Sendable conformance to a swift data model was breaking concurrency rules, but I wanted to check with the community to see what everyone thinks. Best, Taylor
Posted
by taychap.
Last updated
.
Post not yet marked as solved
1 Replies
562 Views
I just installed Xcode beta 6 and tried compiling the SwiftData sample app. It fails with a couple of dozen compile errors. Clearly this must have worked for WWDC23 so what's gone wrong? The following says type 'Card' does not conform to protocol 'PersistentModel' @Model final class Card: PersistentModel { This seems pretty basic. Any suggestions
Posted Last updated
.
Post marked as solved
1 Replies
430 Views
I tried coding along with the WWDC23 'Dive Deeper into SwiftData' video but can't get the sample code to compile. For example the Card class fails with lots of errors associated with @Model. The first of these is: Type 'Card' does not conform to protocol 'PersistentModel' import SwiftUI import SwiftData @Model final class Card { var front: String var back: String var creationDate: Date init(front: String, back: String, creationDate: Date = .now) { self.front = front self.back = back self.creationDate = creationDate } } On the other hand the following stand alone code (in it's own project) compiles without error. So I am confused and a little fed up with Apple publishing sample code that doesn't compile. import SwiftData @Model final class Card { var front: String var back: String var creationDate: Date init(front: String, back: String, creationDate: Date = .now) { self.front = front self.back = back self.creationDate = creationDate } } struct ContentView: View { var body: some View { VStack { Image(systemName: "globe") .imageScale(.large) .foregroundStyle(.tint) Text("Hello, world!") } .padding() } } #Preview { ContentView() }
Posted Last updated
.
Post not yet marked as solved
1 Replies
682 Views
There is a new Relationship macro in Xcode Beta 6. The macro includes two new arguments: minimumModelCount and maximumModelCount. I wonder if anyone knows what these values are for and if there is another change under the hood. Relationship( _ options: PropertyOptions..., deleteRule: Schema.Relationship.DeleteRule = .nullify, minimumModelCount: Int? = 0, maximumModelCount: Int? = 0, originalName: String? = nil, inverse: AnyKeyPath? = nil, hashModifier: String? = nil )
Posted
by macrojd.
Last updated
.
Post marked as solved
4 Replies
3.5k Views
re: the SwiftData session "Create an app with SwifData" (https://developer.apple.com/videos/play/wwdc2023/10154) I corrected the @MainActor issue, but it seems to only work with the main ContentView and not other views. I get the following error for TripListItem for example : failed to find a currently active container for Trip
Posted
by grangej.
Last updated
.
Post not yet marked as solved
5 Replies
1.3k Views
Hi, I get this error Thread 1: Fatal error: Illegal attempt to use a nil as an Attribute - type + CustomType when trying to use SwiftData on one of my main views, I wasn't seeing this error when I was working with other data types but some reason this started happening all of a sudden. Any clues as to what it might be?
Posted
by JB184351.
Last updated
.
Post not yet marked as solved
0 Replies
619 Views
I have two models a Person and a Possession the Person model has a one to many relationship to the Possession model. meaning each possession can only have one person but a person can have multiple possessions. I have set my model like the following Person: @Model class Person { @Attribute(.unique) let personID: String @Relationship(.cascade, inverse: \Possession.person) var possetions: [Possession]? init(id: String, possessions: [Possession]) { self.personID = id self.possetions = possessions } } Possession: @Model class Possession { @Attribute(.unique) let id: String let name: String? var person: Person? init(id: String, name: String, person: Person) { self.id = id self.name = name self.person = person } } If i set a breakpoint i see that all the posessions are loaded into the memory this is something i do not want to happen. In Core Data we get a relationship fault however, i am not seeing the same behavior in SwiftData. here's how my view is implemented struct ContentView: View { @Environment(\.modelContext) private var modelContext @EnvironmentObject private var navigationStore: NavigationStore @Query() private var people: [Person] var body: some View { List { ForEach(people) { person in NavigationLink(value: person) { VStack { Text(person.personID) } } .swipeActions { Button("Delete") { modelContext.delete(person) } } } } .toolbar(content: { Button("Add") { let newPErson = Person(id: UUID().uuidString, possessions: []) modelContext.insert(newPErson) do { try modelContext.save() } catch { assertionFailure("\(error)") } } }) .navigationDestination(for: Person.self) { person in Text("hello") } } } at the launch i do not want posessions to be loaded into the memory. I want them loaded when they are being used.
Posted
by lukdor.
Last updated
.
Post not yet marked as solved
2 Replies
691 Views
Hi all, I am trying to render my SwiftUI views that uses SwiftData classes using sample data using the approach shown in the example code of wwdc2023-10196: @MainActor #Preview { TripsWidgetEntryView() .modelContainer(PreviewSampleData.container) } Unfortunately this seems no longer valid. Indeed I get this error: I then tried to remove the @MainActor as suggested, but the error in then moved to another level: What do you suggest to be the best approach to have back my preview working? I am using Xcode Beta 4 - 15A5195m
Posted Last updated
.
Post not yet marked as solved
1 Replies
849 Views
I am getting the following error on this line of code @Query(sort: \.id, order: .reverse) private var artList: [ArtInventory] Cannot infer key path type from context; consider explicitly specifying a root type So, I select fix and then the line of code then look like this @Query(sort: \<#Root#>.id, order: .reverse) private var artList: [ArtInventory] with this error Invalid component of Swift key path Some seems to have changed with the @Query macro in beta 5, which now needs a root type, but not sure how to proceed. Any ideas how to fix?
Posted
by BigEagle.
Last updated
.
Post not yet marked as solved
0 Replies
577 Views
I've noticed when using @Model instead of @Observable that it bumps the CPU-usage of the app with 10%, since I'm reading values on every frame of render. This seems to cause a deep lookup. Is there a way to read the objects/attributes in memory somehow?
Posted Last updated
.
Post not yet marked as solved
1 Replies
669 Views
I set my active schema to SwiftDataCardSampleEnd, open ContentView.swift, and bring up the Canvas. When I click the little refresh button I get the follow error from Canvas: == DATE: Friday, July 14, 2023 at 9:02:26 AM Eastern Daylight Time 2023-07-14T13:02:26Z == PREVIEW UPDATE ERROR: SchemeBuildError: Failed to build the scheme ”SwiftDataFlashCardSampleEnd” linker command failed with exit code 1 (use -v to see invocation) Link SwiftDataFlashCardSample (arm64): ld: Undefined symbols: unsafeMutableAddressor of self #1 : SwiftDataFlashCardSample.Card in SwiftDataFlashCardSample.Card.creationDate.init : Foundation.Date, referenced from: SwiftDataFlashCardSample.Card.creationDate.init : Foundation.Date in Card.o unsafeMutableAddressor of self #1 : SwiftDataFlashCardSample.Card in SwiftDataFlashCardSample.Card.back.init : Swift.String, referenced from: SwiftDataFlashCardSample.Card.back.init : Swift.String in Card.o unsafeMutableAddressor of self #1 : SwiftDataFlashCardSample.Card in SwiftDataFlashCardSample.Card.front.init : Swift.String, referenced from: SwiftDataFlashCardSample.Card.front.init : Swift.String in Card.o clang: error: linker command failed with exit code 1 (use -v to see invocation) I've made a similar preview in another project where I define a model and I try to use that model in a SwiftUI Canvas preview. I get a very similar error. Basically Canvas is saying it can't find the symbols for the properties on the type. Is there something I'm missing here? Some hidden build setting I need to flip. Or is this just busted?
Posted
by bdunay3.
Last updated
.
Post marked as solved
2 Replies
874 Views
What is the difference between swiftdata and coredata? I am coding by integrating coreda and icloud. As introduced at wwdc, I heard that it can be used more easily in xcode. However, for me who has to sell it tomorrow, the stability of swiftdata after the official release of ios17 in the future is low, and scalability and modification are difficult. If it's difficult, it's a lot of trouble. And the most important thing, is there any difference from coredata by using swiftdata in the experience of my valuable customers who use my program? I'm well aware that everyone is learning and discussing. Thank you for sharing your experience.
Posted Last updated
.
Post not yet marked as solved
2 Replies
1.4k Views
In the WWDC presentations, it was mentioned that you could have multiple modelContexts within one modelContainer. Does anyone know of any examples of a project with multiple modelContexts? Specifically, I'm wondering how you distinguish between the two different modelContexts when doing things like @Query. I'd like to keep different sets of data in separate modelContexts and only Query the one that I want to pull from for a particular view. Thanks in advance!
Posted Last updated
.
Post marked as solved
5 Replies
1.4k Views
Hi all, Has anyone stumbled upon the SwiftData equivalent of @SectionedFetchRequest? Is there a way to do it with @Query? I'll keep going through the documentation but if anyone has an answer, it would be much appreciated!! Thank you.
Posted Last updated
.
Post marked as solved
2 Replies
1.8k Views
When trying to delete the element from my list, I always got error in my model. get { _$observationRegistrar.access(self, keyPath: \.id) return self.getValue(for: \.id) <-- ERROR: Thread 1: EXC_BREAKPOINT (code=1, subcode=0x1a949aefc) } Because I am new in development, I don't know how to solve it.
Posted Last updated
.
Post marked as solved
10 Replies
2.7k Views
Overview I have 2 models: Deparment and Student Each Department can contain multiple students Each Student can only be in one Department I have DepartmentList, tapping on the department should take it to the StudentList which lists all students in the department Problem When I use Query in StudentList to filter only students for a specific department id, no students are shown. Questions: What should I do to list the students in a department? (see complete code below). let filter = #Predicate<Student> { student in student.department?.id == departmentID } let query = Query(filter: filter, sort: \.name) _students = query Complete code App @main struct SchoolApp: App { var body: some Scene { WindowGroup { ContentView() } .modelContainer(for: [Department.self, Student.self]) } } Department import Foundation import SwiftData @Model class Department { var id: UUID var name: String var students: [Student] init( id: UUID, name: String, students: [Student] = [] ) { self.id = id self.name = name self.students = students } } Student import Foundation import SwiftData @Model class Student { var id: UUID var name: String @Relationship(inverse: \Department.students) var department: Department? init( id: UUID, name: String, department: Department? = nil ) { self.id = id self.name = name self.department = department } } ContentView import SwiftUI struct ContentView: View { @State private var selectedDepartment: Department? var body: some View { NavigationSplitView { DepartmentList(selectedDepartment: $selectedDepartment) } detail: { if let department = selectedDepartment { StudentList(department: department) } else { Text("no department selected") } } .task { printStoreFilePath() } } private func printStoreFilePath() { let urls = FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask) if let path = urls.map({ $0.path(percentEncoded: false) }).first { print("Storage: \(path)") } } } DepartmentList import SwiftUI import SwiftData struct DepartmentList: View { @Binding var selectedDepartment: Department? @Query(sort: \.name) private var departments: [Department] @Environment(\.modelContext) private var modelContext var body: some View { List(selection: $selectedDepartment) { ForEach(departments) { department in NavigationLink(value: department) { Text(department.name) } } } .toolbar { ToolbarItem { Button { addDepartment() } label: { Label("Add", systemImage: "plus") } } } } private func addDepartment() { guard let index = (1000..<10000).randomElement() else { return } let department = Department(id: UUID(), name: "Department \(index)") modelContext.insert(department) } } StudentList import SwiftUI import SwiftData struct StudentList: View { var department: Department @Query private var students: [Student] @Environment(\.modelContext) private var modelContext init(department: Department) { self.department = department let departmentID = department.id let filter = #Predicate<Student> { student in student.department?.id == departmentID } let query = Query(filter: filter, sort: \.name) _students = query } var body: some View { List { ForEach(students) { student in Text(student.name) } } .toolbar { ToolbarItem { Button { addStudent() } label: { Label("Add", systemImage: "plus") } } } } private func addStudent() { guard let index = (1000..<10000).randomElement() else { return } let student = Student( id: UUID(), name: "Student \(index)", department: department ) modelContext.insert(student) } }
Posted
by newwbee.
Last updated
.