Fixes not updating featured apps installation status on source detail page

This commit is contained in:
Riley Testut
2024-01-23 16:50:55 -06:00
committed by Magesh K
parent 6d7d06a85e
commit 79fc75edbd
2 changed files with 20 additions and 31 deletions

View File

@@ -72,6 +72,9 @@ class SourceDetailContentViewController: UICollectionViewController
self.dataSource.proxy = self
self.collectionView.dataSource = self.dataSource
self.collectionView.prefetchDataSource = self.dataSource
let context = self.source.managedObjectContext ?? DatabaseManager.shared.viewContext
NotificationCenter.default.addObserver(self, selector: #selector(SourceDetailContentViewController.didChangeApps), name: NSManagedObjectContext.didChangeObjectsNotification, object: context)
}
override func viewSafeAreaInsetsDidChange()
@@ -451,6 +454,23 @@ private extension SourceDetailContentViewController
{
UIApplication.shared.open(installedApp.openAppURL)
}
@objc func didChangeApps(_ notification: Notification)
{
// Make sure to include refreshed objects to catch all merged changes.
let updatedObjects = notification.userInfo?[NSUpdatedObjectsKey] as? Set<NSManagedObject> ?? []
let refreshedObjects = notification.userInfo?[NSRefreshedObjectsKey] as? Set<NSManagedObject> ?? []
let changedAppIndexes = updatedObjects.union(refreshedObjects).compactMap { $0 as? StoreApp }.compactMap { self.appsDataSource.items.firstIndex(of: $0) }
let indexPaths = changedAppIndexes.map { IndexPath(item: $0, section: Section.featuredApps.rawValue) }
guard !indexPaths.isEmpty else { return }
// Async so that AppManager.installationProgress(for:) is nil when we update.
DispatchQueue.main.async {
self.collectionView.reloadItems(at: indexPaths)
}
}
}
extension SourceDetailContentViewController: ScrollableContentViewController

View File

@@ -84,38 +84,7 @@ class SourceDetailViewController: HeaderContentViewController<SourceHeaderView,
init?(source: Source, coder: NSCoder)
{
let isolatedContext: NSManagedObjectContext
if source.managedObjectContext == DatabaseManager.shared.viewContext
{
do
{
// Source is persisted to disk, so we can create a new view context
// that's pinned to current query generation to ensure information
// doesn't disappear out from under us if we remove (delete) the source.
let context = DatabaseManager.shared.persistentContainer.newViewContext(withParent: nil)
try context.setQueryGenerationFrom(.current)
isolatedContext = context
}
catch
{
print("[ATLog] Failed to set query generation for context.", error)
isolatedContext = DatabaseManager.shared.persistentContainer.newViewContext(withParent: source.managedObjectContext)
}
}
else
{
// Source is not persisted to disk, so create child view context with source's managedObjectContext as parent.
// This also maintains a strong reference to source.managedObjectContext, which may be necessary.
isolatedContext = DatabaseManager.shared.persistentContainer.newViewContext(withParent: source.managedObjectContext)
}
// Ignore changes from other contexts so we can delete source without UI automatically updating.
isolatedContext.automaticallyMergesChangesFromParent = false
let source = isolatedContext.object(with: source.objectID) as! Source
self.source = source
self.viewModel = ViewModel(source: source)
super.init(coder: coder)