From 753fb740fed4c8d4c2e7adb6d4facec8a882d24c Mon Sep 17 00:00:00 2001 From: Riley Testut Date: Sat, 16 May 2020 15:13:12 -0700 Subject: [PATCH] Adds RemoveAppOperation for removing inactive apps --- AltStore.xcodeproj/project.pbxproj | 4 + AltStore/Operations/RemoveAppOperation.swift | 83 ++++++++++++++++++++ 2 files changed, 87 insertions(+) create mode 100644 AltStore/Operations/RemoveAppOperation.swift diff --git a/AltStore.xcodeproj/project.pbxproj b/AltStore.xcodeproj/project.pbxproj index b0d3c9c5..7223e682 100644 --- a/AltStore.xcodeproj/project.pbxproj +++ b/AltStore.xcodeproj/project.pbxproj @@ -51,6 +51,7 @@ BF44CC6C232AEB90004DA9C3 /* LaunchAtLogin.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BF44CC6A232AEB74004DA9C3 /* LaunchAtLogin.framework */; }; BF44CC6D232AEB90004DA9C3 /* LaunchAtLogin.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = BF44CC6A232AEB74004DA9C3 /* LaunchAtLogin.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; BF44EEF0246B08BA002A52F2 /* BackupController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF44EEEF246B08BA002A52F2 /* BackupController.swift */; }; + BF44EEFC246B4550002A52F2 /* RemoveAppOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF44EEFB246B4550002A52F2 /* RemoveAppOperation.swift */; }; BF458690229872EA00BD7491 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF45868F229872EA00BD7491 /* AppDelegate.swift */; }; BF458694229872EA00BD7491 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = BF458693229872EA00BD7491 /* Assets.xcassets */; }; BF458697229872EA00BD7491 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = BF458695229872EA00BD7491 /* Main.storyboard */; }; @@ -372,6 +373,7 @@ BF43002F22A71C960051E2BC /* UserDefaults+AltStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UserDefaults+AltStore.swift"; sourceTree = ""; }; BF44CC6A232AEB74004DA9C3 /* LaunchAtLogin.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = LaunchAtLogin.framework; path = Carthage/Build/Mac/LaunchAtLogin.framework; sourceTree = ""; }; BF44EEEF246B08BA002A52F2 /* BackupController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BackupController.swift; sourceTree = ""; }; + BF44EEFB246B4550002A52F2 /* RemoveAppOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RemoveAppOperation.swift; sourceTree = ""; }; BF45868D229872EA00BD7491 /* AltServer.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AltServer.app; sourceTree = BUILT_PRODUCTS_DIR; }; BF45868F229872EA00BD7491 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; BF458693229872EA00BD7491 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; @@ -1292,6 +1294,7 @@ BF56D2AB23DF8E170006506D /* FetchAppIDsOperation.swift */, BFC57A642416C72400EB891E /* DeactivateAppOperation.swift */, BFCCB519245E3401001853EA /* VerifyAppOperation.swift */, + BF44EEFB246B4550002A52F2 /* RemoveAppOperation.swift */, BF3432FA246B894F0052F4A1 /* BackupAppOperation.swift */, ); path = Operations; @@ -1871,6 +1874,7 @@ BF41B806233423AE00C593A3 /* TabBarController.swift in Sources */, BFDB6A0B22AAEDB7007EA6D6 /* Operation.swift in Sources */, BF770E6722BD57C4002A40FE /* BackgroundTaskManager.swift in Sources */, + BF44EEFC246B4550002A52F2 /* RemoveAppOperation.swift in Sources */, BF100C54232D7DAE006A8926 /* StoreAppPolicy.swift in Sources */, BF100C50232D7CD1006A8926 /* AltStoreToAltStore2.xcmappingmodel in Sources */, BF3D64B022E8D4B800E9056B /* AppContentViewControllerCells.swift in Sources */, diff --git a/AltStore/Operations/RemoveAppOperation.swift b/AltStore/Operations/RemoveAppOperation.swift new file mode 100644 index 00000000..9bb3a050 --- /dev/null +++ b/AltStore/Operations/RemoveAppOperation.swift @@ -0,0 +1,83 @@ +// +// RemoveAppOperation.swift +// AltStore +// +// Created by Riley Testut on 5/12/20. +// Copyright © 2020 Riley Testut. All rights reserved. +// + +import Foundation + +import AltKit + +@objc(RemoveAppOperation) +class RemoveAppOperation: ResultOperation +{ + let context: InstallAppOperationContext + + init(context: InstallAppOperationContext) + { + self.context = context + + super.init() + } + + override func main() + { + super.main() + + if let error = self.context.error + { + self.finish(.failure(error)) + return + } + + guard let server = self.context.server, let installedApp = self.context.installedApp else { return self.finish(.failure(OperationError.invalidParameters)) } + guard let udid = Bundle.main.object(forInfoDictionaryKey: Bundle.Info.deviceID) as? String else { return self.finish(.failure(OperationError.unknownUDID)) } + + installedApp.managedObjectContext?.perform { + let resignedBundleIdentifier = installedApp.resignedBundleIdentifier + + ServerManager.shared.connect(to: server) { (result) in + switch result + { + case .failure(let error): self.finish(.failure(error)) + case .success(let connection): + print("Sending remove app request...") + + let request = RemoveAppRequest(udid: udid, bundleIdentifier: resignedBundleIdentifier) + connection.send(request) { (result) in + print("Sent remove app request!") + + switch result + { + case .failure(let error): self.finish(.failure(error)) + case .success: + print("Waiting for remove app response...") + connection.receiveResponse() { (result) in + print("Receiving remove app response:", result) + + switch result + { + case .failure(let error): self.finish(.failure(error)) + case .success(.error(let response)): self.finish(.failure(response.error)) + case .success(.removeApp): + DatabaseManager.shared.persistentContainer.performBackgroundTask { (context) in + self.progress.completedUnitCount += 1 + + let installedApp = context.object(with: installedApp.objectID) as! InstalledApp + installedApp.isActive = false + self.finish(.success(installedApp)) + } + + case .success: self.finish(.failure(ALTServerError(.unknownResponse))) + } + } + } + } + } + } + } + } +} +