Search code examples
swiftuiswiftdata

Problem sorting list using SwiftData and returning the right item to delete


I have a tripDetailView that is passed a model

var trip: TripSummariesSD

That I sort

let sortedTrip = trip.toTripJournal?.sorted { $0.timestamp < $1.timestamp}

Then I list

List {
  //ForEach(trip.toTripJournal!, id: \.self) { detail in
  ForEach(sortedTrip!, id: \.self) { detail in
  Text("\(formatDateStampA(detail.timestamp)) \(detail.latitude), \(detail.longitude) \(formatMPH(convertMPStoMPH(detail.speed))) mph")
  }
  .onDelete(perform: deleteTripJournalEntry)
}

private func deleteTripJournalEntry(at offsets: IndexSet) {
  offsets.forEach { index in
            
    print("index: \(index)"
    print("item :  \(trip.toTripJournal![index].timestamp)")
                        
    tripJournalEntryToDelete = trip.toTripJournal![index]
    showDeleteConfirmation = true
    }
}

If I run as shown my list is not sorted but when I select an entry to delete it does return the right index and item. But if I swap to my sortedTrip I show a properly sorted list and get the right index but wrong item. I would like to show the list sorted and have it select the right item. It looks like between the data and the list I can't get them to sync up.

FYI, I did load the toTripJournal information into SwiftData in sorted date order but when I bring it up here the items at the data level appear to be at random.

A sorted list that returns the correct item to delete in SwiftData


Solution

  • try something like this approach, finding the trip to delete in the sorted array (when using ForEach(sortedTrip!, id: \.self)...), and finding the equivalent trip index (based on id or some other unique feature) in the trip.toTripJournal array. Then you can use that index to locate the trip to delete.

    Example code:

    func deleteTripJournalEntry(at offsets: IndexSet) {
        offsets.forEach { index in
            
            print("index: \(index)")
            print("item : \(trip.toTripJournal![index].timestamp)")
            
            // get the trip from the sortedTrip array
            let trip = sortedTrip[index]
            
            // find the index of that trip in the trip.toTripJournal array, based on id
            if let jIndex = trip.toTripJournal.firstIndex(where: { $0.id == trip.id}) {
                tripJournalEntryToDelete = trip.toTripJournal![jIndex] // <--- here
                showDeleteConfirmation = true
                // do deletions here
                // sortedTrip.remove(at: index)
                // context delete
                // ...
            }
        }
    }