How do I implement drop operation in UICollectionView drag and drop with an async data source and cell registration?

I have a UICollectionView tied to a UICollectionViewDiffableDataSource, and I'm generating and applying snapshots to the datasource on a background serial queue, and generating cells using UICollectionViewCellRegistration. I'm working on supporting reordering of the contents of the collection view via drag and drop, and I'm having trouble with what to do in collectionView:performDropWithCoordinator: so the reorder animation looks right.

Normally, I would do something like this:

-(void)collectionView:(UICollectionView *)collectionView performDropWithCoordinator:(id<UICollectionViewDropCoordinator>)coordinator
{
  NSIndexPath *sourcePath = (NSIndexPath *)coordinator.items.firstObject.dragItem.localObject;
  NSInteger fromIndex = sourcePath.item;
  NSInteger toIndex = coordinator.destinationIndexPath.item;
  NSNumber *fromItem = [self.datasource itemIdentifierForIndexPath:sourcePath];
  NSNumber *toItem = [self.datasource itemIdentifierForIndexPath:coordinator.destinationIndexPath];

  //Do the move in the data model
  [MyModel moveItemFrom:fromIndex to:toIndex];

  //Do the move in the datasource. This is the data source equivalent of:
  //[collectionView moveItemAtIndexPath:sourcePath toIndexPath:coordinator.destinationIndexPath];

  NSDiffableDataSourceSnapshot *snap = self.datasource.snapshot;
  if (toIndex < fromIndex)
    [snap moveItemWithIdentifier:fromItem beforeItemWithIdentifier:toItem];
  else
    [snap moveItemWithIdentifier:fromItem afterItemWithIdentifier:toItem];

  [self.dataSource applySnapshot:snap animated:YES];

  //Drop the item
  [coordinator dropItem:coordinator.items.firstObject.dragItem toItemAtIndexPath:coordinator.destinationIndexPath];
}

But because my datasource updates happen on a background queue, I have to do at least the snapshot generation and application asynchronously, and I'd like to do the actual data model modification there too to avoid hangs. And I need to call dropItem on the coordinator on the main queue in this method. This results in an odd animation where the dropped item momentarily disappears (when drop is called) and then reappears (when the data source is updated on the background queue).

The best idea I have so far is to use UICollectionViewDropPlaceholder to hold the place in the collection view until the data source is updated. But to create a placeholder I need a cell reuse identifier (docs on init method), and I don't have one of those because I'm creating my cells using cell registrations.

So my question: what do I do in the performDrop method to make this work correctly? If the placeholder is the right idea, how do I use it in this situation?

Even when you're using the new cell registration API, you can still manually register reuse identifiers using the older API. This will allow you to use drop placeholders. Cell registrations are not mutually exclusive with manual reuse identifiers and dequeueing, you can mix & match if needed.

Related: UICollectionViewDiffableDataSource directly supports reordering as of iOS 14, but I can't get it to work without list cells that have reorder accessories: https://developer.apple.com/forums/thread/693913

How do I implement drop operation in UICollectionView drag and drop with an async data source and cell registration?
 
 
Q