Fix crash when searching

This commit is contained in:
Shadowfacts 2020-05-10 15:47:50 -04:00
parent 9812d4aff2
commit 5a098df931
Signed by: 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 {
try! self.backgroundContext.save()
}
completion?()
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
if self.dataSource.snapshot().numberOfItems == 0 {
activityIndicator.isHidden = false
activityIndicator.startAnimating()
}
activityIndicator.isHidden = false
activityIndicator.startAnimating()
let request = Client.search(query: query, resolve: true, limit: 10)
mastodonController.run(request) { (response) in
@ -131,24 +129,42 @@ class SearchResultsViewController: EnhancedTableViewController {
}
guard self.currentQuery == query else { return }
let oldSnapshot = self.dataSource.snapshot()
var snapshot = NSDiffableDataSourceSnapshot<Section, Item>()
if self.onlySections.contains(.accounts) && !results.accounts.isEmpty {
snapshot.appendSections([.accounts])
snapshot.appendItems(results.accounts.map { .account($0.id) }, toSection: .accounts)
self.mastodonController.persistentContainer.addAll(accounts: 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)
self.mastodonController.persistentContainer.addAll(statuses: results.statuses)
self.mastodonController.persistentContainer.addAll(accounts: results.statuses.map { $0.account })
}
self.dataSource.apply(snapshot)
self.mastodonController.persistentContainer.performBatchUpdates({ (context, addAccounts, addStatuses) in
// todo: reference count accounts
// oldSnapshot.itemIdentifiers(inSection: .accounts).forEach { (item) in
// guard case let .account(id) = item else { return }
// self.mastodonController.persistentContainer.account(for: id, in: context)?.decrementReferenceCount()
// }
oldSnapshot.itemIdentifiers(inSection: .statuses).forEach { (item) in
guard case let .status(id, _) = item else { return }
self.mastodonController.persistentContainer.status(for: id, in: context)?.decrementReferenceCount()
}
if self.onlySections.contains(.accounts) && !results.accounts.isEmpty {
snapshot.appendSections([.accounts])
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)
}
})
}
}