Fix crash when searching

This commit is contained in:
Shadowfacts 2020-05-10 15:47:50 -04:00
parent 9812d4aff2
commit 5a098df931
Signed by untrusted user: shadowfacts
GPG Key ID: 94A5AB95422746E5
2 changed files with 61 additions and 22 deletions

View File

@ -78,8 +78,8 @@ class MastodonCachePersistentStore: NSPersistentContainer {
if self.backgroundContext.hasChanges { if self.backgroundContext.hasChanges {
try! self.backgroundContext.save() try! self.backgroundContext.save()
} }
completion?()
statuses.forEach { self.statusSubject.send($0.id) } statuses.forEach { self.statusSubject.send($0.id) }
completion?()
} }
} }
@ -142,4 +142,27 @@ class MastodonCachePersistentStore: NSPersistentContainer {
} }
} }
func performBatchUpdates(_ block: @escaping (_ context: NSManagedObjectContext, _ addAccounts: ([Account]) -> Void, _ addStatuses: ([Status]) -> Void) -> Void, completion: (() -> Void)? = nil) {
backgroundContext.perform {
var updatedAccounts = [String]()
var updatedStatuses = [String]()
block(self.backgroundContext, { (accounts) in
accounts.forEach { self.upsert(account: $0) }
updatedAccounts.append(contentsOf: accounts.map { $0.id })
}, { (statuses) in
statuses.forEach { self.upsert(status: $0, incrementReferenceCount: true) }
updatedStatuses.append(contentsOf: statuses.map { $0.id })
})
updatedAccounts.forEach(self.accountSubject.send)
updatedStatuses.forEach(self.statusSubject.send)
if self.backgroundContext.hasChanges {
try! self.backgroundContext.save()
}
completion?()
}
}
} }

View File

@ -116,10 +116,8 @@ class SearchResultsViewController: EnhancedTableViewController {
} }
self.currentQuery = query self.currentQuery = query
if self.dataSource.snapshot().numberOfItems == 0 { activityIndicator.isHidden = false
activityIndicator.isHidden = false activityIndicator.startAnimating()
activityIndicator.startAnimating()
}
let request = Client.search(query: query, resolve: true, limit: 10) let request = Client.search(query: query, resolve: true, limit: 10)
mastodonController.run(request) { (response) in mastodonController.run(request) { (response) in
@ -132,23 +130,41 @@ class SearchResultsViewController: EnhancedTableViewController {
guard self.currentQuery == query else { return } guard self.currentQuery == query else { return }
let oldSnapshot = self.dataSource.snapshot()
var snapshot = NSDiffableDataSourceSnapshot<Section, Item>() var snapshot = NSDiffableDataSourceSnapshot<Section, Item>()
if self.onlySections.contains(.accounts) && !results.accounts.isEmpty {
snapshot.appendSections([.accounts]) self.mastodonController.persistentContainer.performBatchUpdates({ (context, addAccounts, addStatuses) in
snapshot.appendItems(results.accounts.map { .account($0.id) }, toSection: .accounts) // todo: reference count accounts
self.mastodonController.persistentContainer.addAll(accounts: results.accounts) // oldSnapshot.itemIdentifiers(inSection: .accounts).forEach { (item) in
} // guard case let .account(id) = item else { return }
if self.onlySections.contains(.hashtags) && !results.hashtags.isEmpty { // self.mastodonController.persistentContainer.account(for: id, in: context)?.decrementReferenceCount()
snapshot.appendSections([.hashtags]) // }
snapshot.appendItems(results.hashtags.map { .hashtag($0) }, toSection: .hashtags)
} oldSnapshot.itemIdentifiers(inSection: .statuses).forEach { (item) in
if self.onlySections.contains(.statuses) && !results.statuses.isEmpty { guard case let .status(id, _) = item else { return }
snapshot.appendSections([.statuses]) self.mastodonController.persistentContainer.status(for: id, in: context)?.decrementReferenceCount()
snapshot.appendItems(results.statuses.map { .status($0.id, .unknown) }, toSection: .statuses) }
self.mastodonController.persistentContainer.addAll(statuses: results.statuses)
self.mastodonController.persistentContainer.addAll(accounts: results.statuses.map { $0.account }) if self.onlySections.contains(.accounts) && !results.accounts.isEmpty {
} snapshot.appendSections([.accounts])
self.dataSource.apply(snapshot) snapshot.appendItems(results.accounts.map { .account($0.id) }, toSection: .accounts)
addAccounts(results.accounts)
}
if self.onlySections.contains(.hashtags) && !results.hashtags.isEmpty {
snapshot.appendSections([.hashtags])
snapshot.appendItems(results.hashtags.map { .hashtag($0) }, toSection: .hashtags)
}
if self.onlySections.contains(.statuses) && !results.statuses.isEmpty {
snapshot.appendSections([.statuses])
snapshot.appendItems(results.statuses.map { .status($0.id, .unknown) }, toSection: .statuses)
addStatuses(results.statuses)
addAccounts(results.statuses.map { $0.account })
}
}, completion: {
DispatchQueue.main.async {
self.dataSource.apply(snapshot)
}
})
} }
} }