As far as I know, SwiftData doesn't necessarily save/query everything in the order in which they were created. So if you want to put a new object at a certain place in the list you don't know for sure if it will be saved nonetheless queried in the order you specify.
A better way of approching this would be to sort the list when you query your data. If you want to sort your list by creation time, I would add a new Date attribute to your model and add a SortDescriptor to your Query.
Like this:
@Model
final class Transcription {
var text: String
var creationDate: Date
init(text: String, creationDate: Date) {
self.text = text
self.creationDate = creationDate
}
}
struct ContentView: View {
@Environment(\.modelContext) var context
@Query(sort: \Transcription.creationDate, order: .reverse) var transcriptions: [Transcription]
var body: some View {
List {
ForEach(transcriptions) { transcription in
Text(transcription.creationDate.formatted(date: .abbreviated, time: .standard))
}
.onDelete { indexSet in
for index in indexSet {
context.delete(transcriptions[index])
}
}
Button("Add new transcription") {
context.insert(Transcription(text: "", creationDate: .now))
}
}
}
}
#Preview {
ContentView()
.modelContainer(for: Transcription.self, inMemory: true)
}
Post
Replies
Boosts
Views
Activity
Don't know if you already got your answer elsewhere but I included a working sample app below.
Like mcomisso already said, to create a new entity, you have to insert it into the database using the ModelContext.
let newItem = GroceryListItem(name: "New Item", stepperValue: 1)
context.insert(newItem)
Where you do this depends on your app.
GroceryListApp.swift
import SwiftUI
import SwiftData
@main
struct GroceryListApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
.modelContainer(for: GroceryListItem.self)
}
}
GroceryListItem.swift
import SwiftData
@Model
final class GroceryListItem {
var name: String
var stepperValue: Int
init(name: String, stepperValue: Int = 1) {
self.name = name
self.stepperValue = stepperValue
}
}
ContentView.swift
import SwiftUI
import SwiftData
struct ContentView: View {
@Environment(\.modelContext) var context
@Query var groceryListItems: [GroceryListItem]
@State private var newItemName: String = ""
var body: some View {
List {
Section {
TextField("New Item", text: $newItemName)
Button("Add new item", action: insertNewItem)
}
Section {
ForEach(groceryListItems) { groceryListItem in
GroceryListItemView(groceryListItem: groceryListItem)
}
.onDelete(perform: deleteItem)
}
}
}
func insertNewItem() {
let newItem = GroceryListItem(name: newItemName)
context.insert(newItem)
newItemName = ""
}
func deleteItem(at indexSet: IndexSet) {
for index in indexSet {
context.delete(groceryListItems[index])
}
}
}
#Preview {
ContentView()
.modelContainer(for: GroceryListItem.self, inMemory: true)
}
GroceryListItemView.swift
import SwiftUI
struct GroceryListItemView: View {
@Bindable var groceryListItem: GroceryListItem
var body: some View {
Stepper("\(groceryListItem.name) (\(groceryListItem.stepperValue)x)", value: $groceryListItem.stepperValue, in: 1...100)
}
}
#Preview {
// Note that @Previewable was introduced in the XCode 16 Beta
@Previewable @State var previewItem = GroceryListItem(name: "Milk")
List {
GroceryListItemView(groceryListItem: previewItem)
}
}
(I like to keep my view body clear of all logic so I extracted the @Binding and the list item into its own view.)
Screenshot