From cd9562c300267c97a74b9bd57abddea4db200624 Mon Sep 17 00:00:00 2001 From: Riley Testut Date: Wed, 24 Jul 2019 13:52:58 -0700 Subject: [PATCH] [AltStore] Checks for updates in background --- AltStore/AppDelegate.swift | 27 +++++++++++++++++++++ AltStore/Managing Apps/AppManager.swift | 2 +- AltStore/Model/InstalledApp.swift | 7 ++++++ AltStore/My Apps/MyAppsViewController.swift | 5 ++-- 4 files changed, 38 insertions(+), 3 deletions(-) diff --git a/AltStore/AppDelegate.swift b/AltStore/AppDelegate.swift index e92d9c24..bb3e6773 100644 --- a/AltStore/AppDelegate.swift +++ b/AltStore/AppDelegate.swift @@ -207,7 +207,34 @@ extension AppDelegate let apps = try result.get() guard let context = apps.first?.managedObjectContext else { return } + + let updatesFetchRequest = InstalledApp.updatesFetchRequest() + updatesFetchRequest.includesPendingChanges = true + + let previousUpdatesFetchRequest = InstalledApp.updatesFetchRequest() + previousUpdatesFetchRequest.includesPendingChanges = false + + let previousUpdates = try context.fetch(previousUpdatesFetchRequest) + try context.save() + + let updates = try context.fetch(updatesFetchRequest) + + for update in updates + { + guard !previousUpdates.contains(where: { $0.app.identifier == update.app.identifier }) else { continue } + + let content = UNMutableNotificationContent() + content.title = NSLocalizedString("New Update Available", comment: "") + content.body = String(format: NSLocalizedString("%@ %@ is now available for download.", comment: ""), update.app.name, update.app.version) + + let request = UNNotificationRequest(identifier: UUID().uuidString, content: content, trigger: nil) + UNUserNotificationCenter.current().add(request) + } + + DispatchQueue.main.async { + UIApplication.shared.applicationIconBadgeNumber = updates.count + } } catch { diff --git a/AltStore/Managing Apps/AppManager.swift b/AltStore/Managing Apps/AppManager.swift index 38c999c4..4e4977ed 100644 --- a/AltStore/Managing Apps/AppManager.swift +++ b/AltStore/Managing Apps/AppManager.swift @@ -311,7 +311,7 @@ private extension AppManager context.group.results[context.appIdentifier] = .success(installedApp) // Save after each installation. - installedApp.managedObjectContext?.perform { + installedApp.managedObjectContext?.performAndWait { do { try installedApp.managedObjectContext?.save() } catch { print("Error saving installed app.", error) } } diff --git a/AltStore/Model/InstalledApp.swift b/AltStore/Model/InstalledApp.swift index b69be65d..4d46a9da 100644 --- a/AltStore/Model/InstalledApp.swift +++ b/AltStore/Model/InstalledApp.swift @@ -49,6 +49,13 @@ extension InstalledApp return NSFetchRequest(entityName: "InstalledApp") } + class func updatesFetchRequest() -> NSFetchRequest + { + let fetchRequest = InstalledApp.fetchRequest() as NSFetchRequest + fetchRequest.predicate = NSPredicate(format: "%K != %K", #keyPath(InstalledApp.version), #keyPath(InstalledApp.app.version)) + return fetchRequest + } + class func fetchAltStore(in context: NSManagedObjectContext) -> InstalledApp? { let predicate = NSPredicate(format: "%K == %@", #keyPath(InstalledApp.app.identifier), App.altstoreAppID) diff --git a/AltStore/My Apps/MyAppsViewController.swift b/AltStore/My Apps/MyAppsViewController.swift index 12448a88..1f261dfe 100644 --- a/AltStore/My Apps/MyAppsViewController.swift +++ b/AltStore/My Apps/MyAppsViewController.swift @@ -104,8 +104,7 @@ private extension MyAppsViewController func makeUpdatesDataSource() -> RSTFetchedResultsCollectionViewPrefetchingDataSource { - let fetchRequest = InstalledApp.fetchRequest() as NSFetchRequest - fetchRequest.predicate = NSPredicate(format: "%K != %K", #keyPath(InstalledApp.version), #keyPath(InstalledApp.app.version)) + let fetchRequest = InstalledApp.updatesFetchRequest() fetchRequest.sortDescriptors = [NSSortDescriptor(keyPath: \InstalledApp.app?.versionDate, ascending: true), NSSortDescriptor(keyPath: \InstalledApp.app?.name, ascending: true)] fetchRequest.returnsObjectsAsFaults = false @@ -226,10 +225,12 @@ private extension MyAppsViewController if self.updatesDataSource.itemCount > 0 { self.navigationController?.tabBarItem.badgeValue = String(describing: self.updatesDataSource.itemCount) + UIApplication.shared.applicationIconBadgeNumber = Int(self.updatesDataSource.itemCount) } else { self.navigationController?.tabBarItem.badgeValue = nil + UIApplication.shared.applicationIconBadgeNumber = 0 } }