From ac62612a18d536a10248bce4272e46f90a141f90 Mon Sep 17 00:00:00 2001 From: Riley Testut Date: Thu, 15 Feb 2024 14:19:34 -0600 Subject: [PATCH] Uses alternate app icon for AltStore in My Apps, if one is chosen --- AltStore/My Apps/MyAppsViewController.swift | 39 +++++++++++++++++++ .../Settings/AltAppIconsViewController.swift | 9 +++++ AltStoreCore/Model/InstalledApp.swift | 10 +++++ 3 files changed, 58 insertions(+) diff --git a/AltStore/My Apps/MyAppsViewController.swift b/AltStore/My Apps/MyAppsViewController.swift index 666c9721..c6477b2c 100644 --- a/AltStore/My Apps/MyAppsViewController.swift +++ b/AltStore/My Apps/MyAppsViewController.swift @@ -111,6 +111,8 @@ class MyAppsViewController: UICollectionViewController, PeekPopPreviewing } (self as PeekPopPreviewing).registerForPreviewing(with: self, sourceView: self.collectionView) + + NotificationCenter.default.addObserver(self, selector: #selector(MyAppsViewController.didChangeAppIcon(_:)), name: UIApplication.didChangeAppIconNotification, object: nil) } override func viewIsAppearing(_ animated: Bool) @@ -1593,6 +1595,43 @@ private extension MyAppsViewController sender.endRefreshing() } } + + @objc func didChangeAppIcon(_ notification: Notification) + { + guard let altStoreApp = InstalledApp.fetchAltStore(in: DatabaseManager.shared.viewContext) else { return } + + // Remove previous icon from cache. + self.activeAppsDataSource.prefetchItemCache.removeObject(forKey: altStoreApp) + self.inactiveAppsDataSource.prefetchItemCache.removeObject(forKey: altStoreApp) + + if let indexPath = self.activeAppsDataSource.fetchedResultsController.indexPath(forObject: altStoreApp) + { + let indexPath = IndexPath(item: indexPath.item, section: Section.activeApps.rawValue) + + if #available(iOS 15, *) + { + self.collectionView.reconfigureItems(at: [indexPath]) + } + else + { + self.collectionView.reloadItems(at: [indexPath]) + } + } + + if let indexPath = self.inactiveAppsDataSource.fetchedResultsController.indexPath(forObject: altStoreApp) + { + let indexPath = IndexPath(item: indexPath.item, section: Section.inactiveApps.rawValue) + + if #available(iOS 15, *) + { + self.collectionView.reconfigureItems(at: [indexPath]) + } + else + { + self.collectionView.reloadItems(at: [indexPath]) + } + } + } } extension MyAppsViewController diff --git a/AltStore/Settings/AltAppIconsViewController.swift b/AltStore/Settings/AltAppIconsViewController.swift index 462bd726..b39e2f10 100644 --- a/AltStore/Settings/AltAppIconsViewController.swift +++ b/AltStore/Settings/AltAppIconsViewController.swift @@ -13,6 +13,11 @@ import AltSign import AltStoreCore import Roxas +extension UIApplication +{ + static let didChangeAppIconNotification = Notification.Name("io.altstore.AppManager.didChangeAppIcon") +} + private final class AltIcon: Decodable { var name: String @@ -190,6 +195,10 @@ extension AltAppIconsViewController alertController.addAction(.ok) self.present(alertController, animated: true) } + else + { + NotificationCenter.default.post(name: UIApplication.didChangeAppIconNotification, object: icon) + } if let selectedIndexPath = self.collectionView.indexPathsForSelectedItems?.first { diff --git a/AltStoreCore/Model/InstalledApp.swift b/AltStoreCore/Model/InstalledApp.swift index e309cbfc..c69c779e 100644 --- a/AltStoreCore/Model/InstalledApp.swift +++ b/AltStoreCore/Model/InstalledApp.swift @@ -159,6 +159,16 @@ public extension InstalledApp func loadIcon(completion: @escaping (Result) -> Void) { + if self.bundleIdentifier == StoreApp.altstoreAppID, let iconName = UIApplication.alt_shared?.alternateIconName + { + // Use alternate app icon for AltStore, if one is chosen. + + let image = UIImage(named: iconName) + completion(.success(image)) + + return + } + let hasAlternateIcon = self.hasAlternateIcon let alternateIconURL = self.alternateIconURL let fileURL = self.fileURL