SwiftUI List reload causes crash

I get a crash when reloading a List based on some search results. The results may change out the sections and rows. The error returned looks like an internal error because sometimes it works and sometimes it crashes on the same search string.


Error:

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Attempt to create two animations for cell'
*** First throw call stack:
(
  0   CoreFoundation                      0x00007fff23afdbde __exceptionPreprocess + 350
  1   libobjc.A.dylib                     0x00007fff5015cb20 objc_exception_throw + 48
  2   CoreFoundation                      0x00007fff23afd958 +[NSException raise:format:arguments:] + 88
  3   Foundation                          0x00007fff255506f5 -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 191
  4   UIKitCore                           0x00007fff47134191 -[_UITableViewUpdateSupport(Private) _setupAnimationsForNewlyInsertedCells] + 1575
  5   UIKitCore                           0x00007fff4713ef73 -[_UITableViewUpdateSupport _setupAnimations] + 118
  6   UIKitCore                           0x00007fff470d5ec4 -[UITableView _updateWithItems:updateSupport:] + 2883
  7   UIKitCore                           0x00007fff470cde73 -[UITableView _endCellAnimationsWithContext:] + 17188
  8   UIKitCore                           0x00007fff470e7c36 -[UITableView endUpdatesWithContext:] + 112
  9   UIKitCore                           0x00007fff470e7de2 -[UITableView _performBatchUpdates:withContext:completion:] + 253
  10  UIKitCore                           0x00007fff470e7efa -[UITableView performBatchUpdates:completion:] + 98
  11  SwiftUI                             0x00007fff2c0a4ff6 $s7SwiftUI25UpdateCoalescingTableView33_BFB370BA5F1BADDC9D83021565761A49LLC19performBatchUpdates_10completionyyycSg_ySbcSgtF + 470
  12  SwiftUI                             0x00007fff2c0a517f $s7SwiftUI25UpdateCoalescingTableView33_BFB370BA5F1BADDC9D83021565761A49LLC19performBatchUpdates_10completionyyycSg_ySbcSgtFTo + 175
  13  SwiftUI                             0x00007fff2c0a71ed $s7SwiftUI19ListCoreCoordinator33_BFB370BA5F1BADDC9D83021565761A49LLC17updateUITableView_4from2toySo0mN0C_xxtF + 1693
  14  SwiftUI                             0x00007fff2c0a5ae1 $s7SwiftUI9_ListCore33_BFB370BA5F1BADDC9D83021565761A49LLV12updateUIView_7contextySo11UITableViewC_AA0L20RepresentableContextVyADyxq_GGtF + 769
  15  SwiftUI                             0x00007fff2c466131 $s7SwiftUI32PlatformViewRepresentableAdaptor33_19642D833A8FE469B137699ED1426762LLV06updateD8Provider_7contexty10UIViewTypeQz_AA0cdE7ContextVyADyxGGtF + 289
  16  SwiftUI                             0x00007fff2c11d086 $s7SwiftUI17PlatformViewChildV6update7contexty14AttributeGraph0H7ContextVyACyxGGz_tFyyXEfU_ + 2086
  17  SwiftUI                             0x00007fff2c117c46 $s7SwiftUI17PlatformViewChildV6update7contexty14AttributeGraph0H7ContextVyACyxGGz_tF + 310
  18  SwiftUI                             0x00007fff2c11e050 $s7SwiftUI17PlatformViewChildVyxG14AttributeGraph07UntypedF0AaeFP7_update_5graph9attributeySv_So10AGGraphRefaSo11AGAttributeatFZTW + 32
  19  AttributeGraph                      0x00007fff2f649a49 $sTA + 25
  20  AttributeGraph                      0x00007fff2f633429 _ZN2AG5Graph11UpdateStack6updateEv + 1111
  21  AttributeGraph                      0x00007fff2f6336e7 _ZN2AG5Graph16update_attributeEjb + 377
  22  AttributeGraph                      0x00007fff2f638263 _ZN2AG8Subgraph6updateEj + 959
  23  SwiftUI                             0x00007fff2bfd8110 $s7SwiftUI9ViewGraphC14runTransaction33_D63C4EB7F2B205694B6515509E76E98BLL2inySo10AGGraphRefa_tF + 224
  24  SwiftUI                             0x00007fff2bfd7e50 $s7SwiftUI9ViewGraphC17flushTransactionsyyFySo10AGGraphRefaXEfU_ + 256
  25  SwiftUI                             0x00007fff2bfd7b8f $s7SwiftUI9ViewGraphC17flushTransactionsyyF + 223
  26  SwiftUI                             0x00007fff2bfdb6e1 $sIg_ytIegr_TRTA + 17
  27  SwiftUI                             0x00007fff2bfe0779 $sIg_ytIegr_TRTA.61 + 9
  28  SwiftUI                             0x00007fff2c329f7b $s7SwiftUI16ViewRendererHostPAAE10withUpdateyqd__qd__yXElF + 59
  29  SwiftUI                             0x00007fff2bfd7d14 $s7SwiftUI9ViewGraphC16asyncTransaction_8mutation5styleyAA0F0V_xAA01_D14Mutation_StyleOtAA0dI0RzlFyycfU_ + 164
  30  SwiftUI                             0x00007fff2bff438c $sIeg_ytIegr_TR + 12
  31  SwiftUI                             0x00007fff2be3abc1 $sIeg_ytIegr_TRTA + 17
  32  SwiftUI                             0x00007fff2be3aae7 $sSo9NSRunLoopC7SwiftUIE14flushObserversyyFZ + 119
  33  SwiftUI                             0x00007fff2be3aa69 $sSo9NSRunLoopC7SwiftUIE11addObserveryyyycFZySo05CFRunbF3RefaSg_So0gB8ActivityVSvSgtcfU_ + 9
  34  SwiftUI                             0x00007fff2be3ab5b $sSo9NSRunLoopC7SwiftUIE11addObserveryyyycFZySo05CFRunbF3RefaSg_So0gB8ActivityVSvSgtcfU_To + 43
  35  CoreFoundation                      0x00007fff23a5feb7 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23
  36  CoreFoundation                      0x00007fff23a5a94e __CFRunLoopDoObservers + 430
  37  CoreFoundation                      0x00007fff23a5afca __CFRunLoopRun + 1514
  38  CoreFoundation                      0x00007fff23a5a6b6 CFRunLoopRunSpecific + 438
  39  GraphicsServices                    0x00007fff38016bb0 GSEventRunModal + 65
  40  UIKitCore                           0x00007fff46f0990f UIApplicationMain + 1621
  41  Avenue                              0x000000010a554e6b main + 75
  42  libdyld.dylib                       0x00007fff50fe1cf5 start + 1
  43  ???                                 0x0000000000000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException


The List code is:

struct SearchView: View {
    
    @EnvironmentObject var searchData: SearchData
    @EnvironmentObject var locationData: LocationData
    
    var body: some View {
        VStack {
            SearchBarView(text: $searchData.searchString, isActiveBar: searchData.isSearchActive)
                .padding([.leading, .top, .trailing])
            Text("You can search addresses or contact names")
                .font(.caption)
                .foregroundColor(.secondary)
            Divider()
            List {
                SearchResultCurrentLocationRow(currentLocation: locationData.currentLocation)
                ForEach(Array(self.searchData.matches.keys)) { groupKey in
                    
                    Section(header: SearchResultSection(key: groupKey.id)) {
                        ForEach(self.searchData.matches[groupKey]!) { searchResult in
                            
                            SearchResultRow(result: searchResult)
                        }
                    }
                }
            }
        }
            .navigationBarTitle("Add Waypoint")
    }
}
Answered by hobbesthetige in 380884022

Ah, found it. In my section creation, I was casting my dictionary keys into an Array but not sorting them, so the sections would get out of order. Sorted/keeping them in the same order keeps the crash from happening, but it's still weird that reordering sections would cause a crash.

Accepted Answer

Ah, found it. In my section creation, I was casting my dictionary keys into an Array but not sorting them, so the sections would get out of order. Sorted/keeping them in the same order keeps the crash from happening, but it's still weird that reordering sections would cause a crash.

Thank you! I spent so much time trying to figure it out what's the problem! I'm exactly in the same case trying to represent a dictionary that I mapped to a tuple

[(Category: [Item])]

it worked great but I really needed to sort it like that for instance:

private var searchCategories: [(Category, [Item])] {
    viewModel.searchResults
        .map { $0 }
        .sorted(by: \.key.rawValue) // You really need that to avoid crashes!
}

And my views

private var searchList: some View {
    List {
        ForEach(searchCategories, id: \.0, content: searchSection)
    }.modifier(DismissingKeyboardOnSwipe())
}

private func searchSection(category: Category, items: [Item]) -> some View {
    Section(header: header(category: category)) {
        ForEach(items, content: searchItemRow)
    }
}

private func searchItemRow(item: Item) -> some View {
    NavigationLink(destination: ItemDetailView(item: item)) {
        ItemRowView(item: item)
    }
}

I encountered the same error and stumbled onto this thread. Its helped me fix the issue, using another solution - in case anyone is interested. My List displays search results based on two search parameters, and the results were clubbed into Sections, where each Section consolidated the results for one parameter. The List displays fine when the search is first run. But changing the parameters or the interval caused the Sections to change their order leading to the same crash as described on this thread. I solved it by assigning an ID value to the List. And then changed this ID each time the user taps the search button to generate a new search. eg

@State var listID = 1

List {
     ForEach(parameter1){
           Section {
                 //all the rows matching this parameter
           }
     }
}
.id(listID) //this solved the issue

Button(action:{
          self.fetchResults
          self.listID += 1         //increment the ID, thereby causing the List to reset its state and prevents the crash
    }, label: {
          Text("Search")
    }
)


Hope it helps anyone who faces the same crash error!

SwiftUI List reload causes crash
 
 
Q