0

I am trying to update data in SwiftData. The documentation, however, is literally just:

func update(expressions: [String : NSExpression], 
    model: any PersistentModel.Type,
    where predicate: NSPredicate? = nil) throws -> Bool

As a new developer, I have no clue what most of this means or how to use it. My code is below:

try? context.update(expressions ["teamScores":NSExpression(format: "\(teamScores)")], model: CounterModel.self)

It failed with exception of type NSException.

I haven't been able to try much, honestly. With such a new framework having literally been released 6 days ago as of writing this, there isn't much documentation or examples outside of setting up the model, persisting data, and querying the database.

HangarRash
  • 7,314
  • 5
  • 5
  • 32
PaytonDEV
  • 63
  • 1
  • 6
  • 1
    You don't have to use anything to `update` your data, it is all done for you when you use the `@Model`. Just change your data in the UI as you would normally, and that's it, `SwiftData` will take care of it. – workingdog support Ukraine Jun 13 '23 at 01:18
  • thank you! i think it speaks to the absolute need of a swift-native persistence library that I thought it was so much more complicated than this. thanks again! – PaytonDEV Jun 13 '23 at 01:38
  • Have you watched the WWDC videos related to SwiftData? If you haven't then you really should, they are probably the best source of information for now. – Joakim Danielson Jun 13 '23 at 13:00
  • I have, actually. I must’ve missed this if it was covered. They’re really helpful – PaytonDEV Jun 13 '23 at 20:53

2 Answers2

1

To update the data you can bind directly to an object via @Bindable and change the values you want. Changes should then be saved/persisted automatically.

Check out the Build an app with SwiftData session (at 4:11). The code basically boils down to:

@Model
final class Item {
   var text: String
}
struct EditorView: View {
   @Bindable var item: Item

   var body: some View {
      TextField("Item Text", text: $item.text)
   }
}

PS: In this example the Item is fetched via a @Query in the main view and passed on this EditorView.

alexkaessner
  • 1,966
  • 1
  • 14
  • 39
0

To update data in SwiftData, we don't need to touch the modelContext directly. We just need to update the instance and the data would be updated automatically.

Here's an example with simple add list project and keep list tracked when didTapped:

@Model final class AnyItem {
    var name: String
    var didTapped: Bool = false
    init(name: String) {
        self.name = name
    }
}

struct ContentView: View {
    @State var itemName: String = ""
    @Environment(\.modelContext) private var modelContext
    @Query var items: [AnyItem]
    
    var body: some View {
        NavigationStack {
            List {
                Section {
                    TextField("Item name", text: $itemName)
                    Button("Submit", action: addItem)
                }
                
                ForEach(items) { item in
                    Section {
                        Text(item.name)
                        Text("Did tapped: \(item.didTapped.description)")
                    }
                    .onTapGesture {
                        updateItem(item)
                    }
                }
            }
        }
    }
    
    private func addItem() {
        withAnimation {
            let newItem = AnyItem(name: itemName)
            modelContext.insert(newItem)
            itemName = ""
        }
    }
    
    private func updateItem(_ item: AnyItem) {
        withAnimation {
            item.didTapped = true
        }
    }
}

#Preview {
    ContentView()
        .modelContainer(for: AnyItem.self, inMemory: true)
}
Pengguna
  • 4,636
  • 1
  • 27
  • 32