Maybe fix crash when restoring unloaded statuses due to race condition

This commit is contained in:
Shadowfacts 2022-12-31 16:57:13 -05:00
parent 358d81b5cf
commit 5027660b52
2 changed files with 13 additions and 10 deletions

View File

@ -256,18 +256,19 @@ class MastodonCachePersistentStore: NSPersistentCloudKitContainer {
return statusMO return statusMO
} }
func addAll(statuses: [Status], completion: (() -> Void)? = nil) { func addAll(statuses: [Status], in context: NSManagedObjectContext? = nil, completion: (() -> Void)? = nil) {
backgroundContext.perform { let context = context ?? backgroundContext
statuses.forEach { self.upsert(status: $0, context: self.backgroundContext) } context.perform {
self.save(context: self.backgroundContext) statuses.forEach { self.upsert(status: $0, context: context) }
self.save(context: context)
statuses.forEach { self.statusSubject.send($0.id) } statuses.forEach { self.statusSubject.send($0.id) }
completion?() completion?()
} }
} }
func addAll(statuses: [Status]) async { func addAll(statuses: [Status], in context: NSManagedObjectContext? = nil) async {
return await withCheckedContinuation { continuation in return await withCheckedContinuation { continuation in
addAll(statuses: statuses) { addAll(statuses: statuses, in: context) {
continuation.resume() continuation.resume()
} }
} }

View File

@ -367,17 +367,19 @@ class TimelineViewController: UIViewController, TimelineLikeCollectionViewContro
} }
} }
} }
await mastodonController.persistentContainer.addAll(statuses: statuses) await mastodonController.persistentContainer.addAll(statuses: statuses, in: mastodonController.persistentContainer.viewContext)
} }
private func applyItemsToRestore(position: TimelinePosition) { private func applyItemsToRestore(position: TimelinePosition) {
var snapshot = NSDiffableDataSourceSnapshot<Section, Item>() var snapshot = NSDiffableDataSourceSnapshot<Section, Item>()
snapshot.appendSections([.statuses]) snapshot.appendSections([.statuses])
let statusIDs = position.statusIDs
let centerStatusID = position.centerStatusID
let items = position.statusIDs.map { Item.status(id: $0, collapseState: .unknown, filterState: .unknown) } let items = position.statusIDs.map { Item.status(id: $0, collapseState: .unknown, filterState: .unknown) }
snapshot.appendItems(items, toSection: .statuses) snapshot.appendItems(items, toSection: .statuses)
dataSource.apply(snapshot, animatingDifferences: false) { dataSource.apply(snapshot, animatingDifferences: false) {
if let centerID = position.centerStatusID, if let centerStatusID,
let index = position.statusIDs.firstIndex(of: centerID), let index = statusIDs.firstIndex(of: centerStatusID),
let indexPath = self.dataSource.indexPath(for: items[index]) { let indexPath = self.dataSource.indexPath(for: items[index]) {
// it sometimes takes multiple attempts to convert on the right scroll position // it sometimes takes multiple attempts to convert on the right scroll position
// since we're dealing with a bunch of unmeasured cells, so just try a few times in a loop // since we're dealing with a bunch of unmeasured cells, so just try a few times in a loop
@ -392,7 +394,7 @@ class TimelineViewController: UIViewController, TimelineLikeCollectionViewContro
break break
} }
} }
stateRestorationLogger.fault("TimelineViewController: restored statuses with center ID \(centerID)") stateRestorationLogger.fault("TimelineViewController: restored statuses with center ID \(centerStatusID)")
} else { } else {
stateRestorationLogger.fault("TimelineViewController: restored statuses, but couldn't find center ID") stateRestorationLogger.fault("TimelineViewController: restored statuses, but couldn't find center ID")
} }