From 04d9f760ad6fa4e5bfc933018729c07b7aee1b30 Mon Sep 17 00:00:00 2001 From: nythepegasus Date: Mon, 23 Oct 2023 10:12:09 -0400 Subject: [PATCH 01/29] Fix AltWidget App Group issue --- AltWidget/Info.plist | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AltWidget/Info.plist b/AltWidget/Info.plist index 4a64486e3..88c39aef9 100644 --- a/AltWidget/Info.plist +++ b/AltWidget/Info.plist @@ -4,8 +4,8 @@ ALTAppGroups - group.com.SideStore.SideStore group.$(APP_GROUP_IDENTIFIER) + group.com.SideStore.SideStore CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE) From 35ee92db12c7dc2e1b5b4e1967493c4c2b3d138b Mon Sep 17 00:00:00 2001 From: Spidy123222 <64176728+Spidy123222@users.noreply.github.com> Date: Mon, 23 Oct 2023 13:12:23 -0700 Subject: [PATCH 02/29] Change pairing file link with new wiki link Signed-off-by: Spidy123222 <64176728+Spidy123222@users.noreply.github.com> --- AltStore/LaunchViewController.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AltStore/LaunchViewController.swift b/AltStore/LaunchViewController.swift index f63ddc2cf..fde8e34ee 100644 --- a/AltStore/LaunchViewController.swift +++ b/AltStore/LaunchViewController.swift @@ -81,7 +81,7 @@ final class LaunchViewController: RSTLaunchViewController, UIDocumentPickerDeleg } else { // Show an alert explaining the pairing file // Create new Alert - let dialogMessage = UIAlertController(title: "Pairing File", message: "Select the pairing file for your device. For more information, go to https://wiki.sidestore.io/guides/install#pairing-process", preferredStyle: .alert) + let dialogMessage = UIAlertController(title: "Pairing File", message: "Select the pairing file for your device. For more information, go to https://wiki.sidestore.io/guides/getting-started/#pairing-file", preferredStyle: .alert) // Create OK button with action handler let ok = UIAlertAction(title: "OK", style: .default, handler: { (action) -> Void in From 2e613e6d1514d831f5249e6cdb4e4234f15c9704 Mon Sep 17 00:00:00 2001 From: nythepegasus Date: Mon, 6 Nov 2023 09:02:49 -0500 Subject: [PATCH 03/29] [skip ci] Update Ignited source URL --- trustedapps.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/trustedapps.json b/trustedapps.json index b49f6235e..194dd58e7 100644 --- a/trustedapps.json +++ b/trustedapps.json @@ -42,7 +42,7 @@ }, { "identifier": "com.litritt.litsource", - "sourceURL": "https://apps.litritt.com/" + "sourceURL": "https://altstore.ignitedemulator.com/" } ] } From 88ab8fa8d7ffda50f72857c85d09355ce055dd18 Mon Sep 17 00:00:00 2001 From: junepark678 <40409848+junepark678@users.noreply.github.com> Date: Sat, 25 Nov 2023 20:03:57 +0900 Subject: [PATCH 04/29] feat: remove reliance on Info.plist for getting udid --- AltStore/Operations/AuthenticationOperation.swift | 3 ++- AltStore/Operations/ResignAppOperation.swift | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/AltStore/Operations/AuthenticationOperation.swift b/AltStore/Operations/AuthenticationOperation.swift index af510de2f..6cecb5b03 100644 --- a/AltStore/Operations/AuthenticationOperation.swift +++ b/AltStore/Operations/AuthenticationOperation.swift @@ -12,6 +12,7 @@ import Network import AltStoreCore import AltSign +import minimuxer enum AuthenticationError: LocalizedError { @@ -593,7 +594,7 @@ private extension AuthenticationOperation func registerCurrentDevice(for team: ALTTeam, session: ALTAppleAPISession, completionHandler: @escaping (Result) -> Void) { - guard let udid = Bundle.main.object(forInfoDictionaryKey: Bundle.Info.deviceID) as? String else { + guard let udid = fetch_udid()?.toString() else { return completionHandler(.failure(OperationError.unknownUDID)) } diff --git a/AltStore/Operations/ResignAppOperation.swift b/AltStore/Operations/ResignAppOperation.swift index 28f180d8c..343f22e18 100644 --- a/AltStore/Operations/ResignAppOperation.swift +++ b/AltStore/Operations/ResignAppOperation.swift @@ -11,6 +11,7 @@ import Roxas import AltStoreCore import AltSign +import minimuxer @objc(ResignAppOperation) final class ResignAppOperation: ResultOperation @@ -181,7 +182,7 @@ private extension ResignAppOperation if app.isAltStoreApp { - guard let udid = Bundle.main.object(forInfoDictionaryKey: Bundle.Info.deviceID) as? String else { throw OperationError.unknownUDID } + guard let udid = fetch_udid()?.toString() as? String else { throw OperationError.unknownUDID } guard let pairingFileString = Bundle.main.object(forInfoDictionaryKey: Bundle.Info.devicePairingString) as? String else { throw OperationError.unknownUDID } additionalValues[Bundle.Info.devicePairingString] = pairingFileString additionalValues[Bundle.Info.deviceID] = udid @@ -202,7 +203,7 @@ private extension ResignAppOperation // The embedded certificate + certificate identifier are already in app bundle, no need to update them. } } - else if infoDictionary.keys.contains(Bundle.Info.deviceID), let udid = Bundle.main.object(forInfoDictionaryKey: Bundle.Info.deviceID) as? String + else if infoDictionary.keys.contains(Bundle.Info.deviceID), let udid = fetch_udid()?.toString() as? String { // There is an ALTDeviceID entry, so assume the app is using AltKit and replace it with the device's UDID. additionalValues[Bundle.Info.deviceID] = udid From 7e92e17429f53463b1b57377389691403bae6b50 Mon Sep 17 00:00:00 2001 From: junepark678 <40409848+junepark678@users.noreply.github.com> Date: Fri, 24 Nov 2023 12:36:54 +0900 Subject: [PATCH 05/29] feat(App IDs): make expiration dates more specific --- AltStore/App IDs/AppIDsViewController.swift | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/AltStore/App IDs/AppIDsViewController.swift b/AltStore/App IDs/AppIDsViewController.swift index 1cd764b42..f5007fd42 100644 --- a/AltStore/App IDs/AppIDsViewController.swift +++ b/AltStore/App IDs/AppIDsViewController.swift @@ -91,13 +91,18 @@ private extension AppIDsViewController cell.bannerView.buttonLabel.isHidden = false - let currentDate = Date() + let formatter = DateComponentsFormatter() + formatter.unitsStyle = .full + formatter.includesApproximationPhrase = false + formatter.includesTimeRemainingPhrase = false + formatter.allowedUnits = [.minute, .hour, .day] - let numberOfDays = expirationDate.numberOfCalendarDays(since: currentDate) - let numberOfDaysText = (numberOfDays == 1) ? NSLocalizedString("1 day", comment: "") : String(format: NSLocalizedString("%@ days", comment: ""), NSNumber(value: numberOfDays)) - cell.bannerView.button.setTitle(numberOfDaysText.uppercased(), for: .normal) - attributedAccessibilityLabel.mutableString.append(String(format: NSLocalizedString("Expires in %@.", comment: ""), numberOfDaysText) + " ") + cell.bannerView.button.setTitle(formatter.string(from: expirationDate, to: Date())?.uppercased(), for: .normal) + + formatter.includesTimeRemainingPhrase = true + + attributedAccessibilityLabel.mutableString.append((formatter.string(from: expirationDate, to: Date()) ?? "Unknown amount of time") + " ") } else { @@ -206,7 +211,7 @@ extension AppIDsViewController: UICollectionViewDelegateFlowLayout **App IDs can't be deleted**, but they do expire after one week. SideStore will automatically renew App IDs for all active apps once they've expired. """, comment: "") - let attributedText = NSAttributedString(markdownRepresentation: text, attributes: [.font: headerView.textLabel.font as Any]) + let attributedText = NSAttributedString(markdownRepresentation: text) headerView.textLabel.attributedText = attributedText } else From c3c31995cede25a2285ecec96c816ddd341dc1f0 Mon Sep 17 00:00:00 2001 From: junepark678 <40409848+junepark678@users.noreply.github.com> Date: Sat, 25 Nov 2023 11:58:39 +0900 Subject: [PATCH 06/29] chore(App IDs): localize Unknown string --- AltStore/App IDs/AppIDsViewController.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AltStore/App IDs/AppIDsViewController.swift b/AltStore/App IDs/AppIDsViewController.swift index f5007fd42..947a2fa72 100644 --- a/AltStore/App IDs/AppIDsViewController.swift +++ b/AltStore/App IDs/AppIDsViewController.swift @@ -102,7 +102,7 @@ private extension AppIDsViewController formatter.includesTimeRemainingPhrase = true - attributedAccessibilityLabel.mutableString.append((formatter.string(from: expirationDate, to: Date()) ?? "Unknown amount of time") + " ") + attributedAccessibilityLabel.mutableString.append((formatter.string(from: expirationDate, to: Date()) ?? NSLocalizedString("Unknown", comment: "")) + " ") } else { From b3d5d976b4a0afdae6bf7857c30a21603e4233bd Mon Sep 17 00:00:00 2001 From: junepark678 <40409848+junepark678@users.noreply.github.com> Date: Sat, 25 Nov 2023 12:00:29 +0900 Subject: [PATCH 07/29] feat(My Apps): make expiration dates more specific --- AltStore.xcodeproj/project.pbxproj | 2 +- AltStore/My Apps/MyAppsViewController.swift | 23 ++++++++++----------- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/AltStore.xcodeproj/project.pbxproj b/AltStore.xcodeproj/project.pbxproj index f4dfb79df..233463c55 100644 --- a/AltStore.xcodeproj/project.pbxproj +++ b/AltStore.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 54; + objectVersion = 52; objects = { /* Begin PBXBuildFile section */ diff --git a/AltStore/My Apps/MyAppsViewController.swift b/AltStore/My Apps/MyAppsViewController.swift index 57de2c8e9..198768923 100644 --- a/AltStore/My Apps/MyAppsViewController.swift +++ b/AltStore/My Apps/MyAppsViewController.swift @@ -329,21 +329,20 @@ private extension MyAppsViewController let currentDate = Date() let numberOfDays = installedApp.expirationDate.numberOfCalendarDays(since: currentDate) - let numberOfDaysText: String - if numberOfDays == 1 - { - numberOfDaysText = NSLocalizedString("1 day", comment: "") - } - else - { - numberOfDaysText = String(format: NSLocalizedString("%@ days", comment: ""), NSNumber(value: numberOfDays)) - } + let formatter = DateComponentsFormatter() + formatter.unitsStyle = .full + formatter.includesApproximationPhrase = false + formatter.includesTimeRemainingPhrase = false + formatter.allowedUnits = [.minute, .hour, .day] + + cell.bannerView.button.setTitle(formatter.string(from: installedApp.expirationDate, to: currentDate)?.uppercased(), for: .normal) - cell.bannerView.button.setTitle(numberOfDaysText.uppercased(), for: .normal) cell.bannerView.button.accessibilityLabel = String(format: NSLocalizedString("Refresh %@", comment: ""), installedApp.name) - - cell.bannerView.accessibilityLabel? += ". " + String(format: NSLocalizedString("Expires in %@", comment: ""), numberOfDaysText) + + formatter.includesTimeRemainingPhrase = true + + cell.bannerView.accessibilityLabel? += ". " + (formatter.string(from: installedApp.expirationDate, to: currentDate) ?? NSLocalizedString("Unknown", comment: "")) + " " // Make sure refresh button is correct size. cell.layoutIfNeeded() From cf373634d71e146c2f18130a4235058da9989d58 Mon Sep 17 00:00:00 2001 From: junepark678 <40409848+junepark678@users.noreply.github.com> Date: Sat, 25 Nov 2023 13:34:23 +0900 Subject: [PATCH 08/29] bugfix(App IDs, My Apps): calculate in correct direction in time (we aren't time travelers) --- AltStore/App IDs/AppIDsViewController.swift | 4 ++-- AltStore/My Apps/MyAppsViewController.swift | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/AltStore/App IDs/AppIDsViewController.swift b/AltStore/App IDs/AppIDsViewController.swift index 947a2fa72..d575098e3 100644 --- a/AltStore/App IDs/AppIDsViewController.swift +++ b/AltStore/App IDs/AppIDsViewController.swift @@ -98,11 +98,11 @@ private extension AppIDsViewController formatter.allowedUnits = [.minute, .hour, .day] - cell.bannerView.button.setTitle(formatter.string(from: expirationDate, to: Date())?.uppercased(), for: .normal) + cell.bannerView.button.setTitle(formatter.string(from: Date(), to: expirationDate)?.uppercased(), for: .normal) formatter.includesTimeRemainingPhrase = true - attributedAccessibilityLabel.mutableString.append((formatter.string(from: expirationDate, to: Date()) ?? NSLocalizedString("Unknown", comment: "")) + " ") + attributedAccessibilityLabel.mutableString.append((formatter.string(from: Date(), to: expirationDate) ?? NSLocalizedString("Unknown", comment: "")) + " ") } else { diff --git a/AltStore/My Apps/MyAppsViewController.swift b/AltStore/My Apps/MyAppsViewController.swift index 198768923..79e291531 100644 --- a/AltStore/My Apps/MyAppsViewController.swift +++ b/AltStore/My Apps/MyAppsViewController.swift @@ -336,13 +336,13 @@ private extension MyAppsViewController formatter.includesTimeRemainingPhrase = false formatter.allowedUnits = [.minute, .hour, .day] - cell.bannerView.button.setTitle(formatter.string(from: installedApp.expirationDate, to: currentDate)?.uppercased(), for: .normal) + cell.bannerView.button.setTitle(formatter.string(from: currentDate, to: installedApp.expirationDate)?.uppercased(), for: .normal) cell.bannerView.button.accessibilityLabel = String(format: NSLocalizedString("Refresh %@", comment: ""), installedApp.name) formatter.includesTimeRemainingPhrase = true - cell.bannerView.accessibilityLabel? += ". " + (formatter.string(from: installedApp.expirationDate, to: currentDate) ?? NSLocalizedString("Unknown", comment: "")) + " " + cell.bannerView.accessibilityLabel? += ". " + (formatter.string(from: currentDate, to: installedApp.expirationDate) ?? NSLocalizedString("Unknown", comment: "")) + " " // Make sure refresh button is correct size. cell.layoutIfNeeded() From 9e2b9b6639bdbada1dda8923d9732353391554ab Mon Sep 17 00:00:00 2001 From: junepark678 <40409848+junepark678@users.noreply.github.com> Date: Sat, 25 Nov 2023 13:46:14 +0900 Subject: [PATCH 09/29] bugfix(App IDs, My Apps): display only necessary information --- AltStore/App IDs/AppIDsViewController.swift | 9 +++++++++ AltStore/My Apps/MyAppsViewController.swift | 11 +++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/AltStore/App IDs/AppIDsViewController.swift b/AltStore/App IDs/AppIDsViewController.swift index d575098e3..450984df0 100644 --- a/AltStore/App IDs/AppIDsViewController.swift +++ b/AltStore/App IDs/AppIDsViewController.swift @@ -97,6 +97,15 @@ private extension AppIDsViewController formatter.includesTimeRemainingPhrase = false formatter.allowedUnits = [.minute, .hour, .day] + let numberOfDays = expirationDate.numberOfCalendarDays(since: Date()) + + + switch numberOfDays + { + case 1...: formatter.allowedUnits = [.day] + case 0: formatter.allowedUnits = [.hour, .minute] + default: formatter.allowedUnits = [.day] + } cell.bannerView.button.setTitle(formatter.string(from: Date(), to: expirationDate)?.uppercased(), for: .normal) diff --git a/AltStore/My Apps/MyAppsViewController.swift b/AltStore/My Apps/MyAppsViewController.swift index 79e291531..f9360e337 100644 --- a/AltStore/My Apps/MyAppsViewController.swift +++ b/AltStore/My Apps/MyAppsViewController.swift @@ -334,8 +334,15 @@ private extension MyAppsViewController formatter.unitsStyle = .full formatter.includesApproximationPhrase = false formatter.includesTimeRemainingPhrase = false - formatter.allowedUnits = [.minute, .hour, .day] - + switch numberOfDays + { + case 1...: formatter.allowedUnits = [.day] + case 0: formatter.allowedUnits = [.hour, .minute] + default: formatter.allowedUnits = [.day] + } + + + cell.bannerView.button.setTitle(formatter.string(from: currentDate, to: installedApp.expirationDate)?.uppercased(), for: .normal) cell.bannerView.button.accessibilityLabel = String(format: NSLocalizedString("Refresh %@", comment: ""), installedApp.name) From 65c998610366c14f549abf1f68280f85302b1682 Mon Sep 17 00:00:00 2001 From: junepark678 <40409848+junepark678@users.noreply.github.com> Date: Sat, 25 Nov 2023 15:09:03 +0900 Subject: [PATCH 10/29] bugfix(App IDs, My Apps): fix date display --- AltStore/App IDs/AppIDsViewController.swift | 11 +---------- AltStore/My Apps/MyAppsViewController.swift | 10 ++++------ 2 files changed, 5 insertions(+), 16 deletions(-) diff --git a/AltStore/App IDs/AppIDsViewController.swift b/AltStore/App IDs/AppIDsViewController.swift index 450984df0..8030e6c9d 100644 --- a/AltStore/App IDs/AppIDsViewController.swift +++ b/AltStore/App IDs/AppIDsViewController.swift @@ -96,16 +96,7 @@ private extension AppIDsViewController formatter.includesApproximationPhrase = false formatter.includesTimeRemainingPhrase = false formatter.allowedUnits = [.minute, .hour, .day] - - let numberOfDays = expirationDate.numberOfCalendarDays(since: Date()) - - - switch numberOfDays - { - case 1...: formatter.allowedUnits = [.day] - case 0: formatter.allowedUnits = [.hour, .minute] - default: formatter.allowedUnits = [.day] - } + formatter.maximumUnitCount = 1 cell.bannerView.button.setTitle(formatter.string(from: Date(), to: expirationDate)?.uppercased(), for: .normal) diff --git a/AltStore/My Apps/MyAppsViewController.swift b/AltStore/My Apps/MyAppsViewController.swift index f9360e337..cf16a87de 100644 --- a/AltStore/My Apps/MyAppsViewController.swift +++ b/AltStore/My Apps/MyAppsViewController.swift @@ -334,12 +334,10 @@ private extension MyAppsViewController formatter.unitsStyle = .full formatter.includesApproximationPhrase = false formatter.includesTimeRemainingPhrase = false - switch numberOfDays - { - case 1...: formatter.allowedUnits = [.day] - case 0: formatter.allowedUnits = [.hour, .minute] - default: formatter.allowedUnits = [.day] - } + + formatter.allowedUnits = [.day, .hour, .minute] + + formatter.maximumUnitCount = 1 From a76aade4ffd783991872c4bb75b0e30bdd469bdc Mon Sep 17 00:00:00 2001 From: junepark678 <40409848+junepark678@users.noreply.github.com> Date: Sat, 25 Nov 2023 15:33:49 +0900 Subject: [PATCH 11/29] chore(App IDs, My Apps): change to use `DateComponentsFormatter.UnitsStyle.abbreviated` --- AltStore/App IDs/AppIDsViewController.swift | 3 +++ AltStore/My Apps/MyAppsViewController.swift | 2 ++ 2 files changed, 5 insertions(+) diff --git a/AltStore/App IDs/AppIDsViewController.swift b/AltStore/App IDs/AppIDsViewController.swift index 8030e6c9d..0fc8ceb1c 100644 --- a/AltStore/App IDs/AppIDsViewController.swift +++ b/AltStore/App IDs/AppIDsViewController.swift @@ -98,6 +98,9 @@ private extension AppIDsViewController formatter.allowedUnits = [.minute, .hour, .day] formatter.maximumUnitCount = 1 + formatter.unitsStyle = DateComponentsFormatter.UnitsStyle.abbreviated + + cell.bannerView.button.setTitle(formatter.string(from: Date(), to: expirationDate)?.uppercased(), for: .normal) formatter.includesTimeRemainingPhrase = true diff --git a/AltStore/My Apps/MyAppsViewController.swift b/AltStore/My Apps/MyAppsViewController.swift index cf16a87de..3da114f22 100644 --- a/AltStore/My Apps/MyAppsViewController.swift +++ b/AltStore/My Apps/MyAppsViewController.swift @@ -336,6 +336,8 @@ private extension MyAppsViewController formatter.includesTimeRemainingPhrase = false formatter.allowedUnits = [.day, .hour, .minute] + + formatter.unitsStyle = DateComponentsFormatter.UnitsStyle.abbreviated formatter.maximumUnitCount = 1 From c2e386a5c5bda1c91669f700be49ceb007801ec0 Mon Sep 17 00:00:00 2001 From: junepark678 <40409848+junepark678@users.noreply.github.com> Date: Sat, 25 Nov 2023 18:15:54 +0900 Subject: [PATCH 12/29] chore(App IDs, My Apps): change back to full --- AltStore/App IDs/AppIDsViewController.swift | 3 --- AltStore/My Apps/MyAppsViewController.swift | 2 -- 2 files changed, 5 deletions(-) diff --git a/AltStore/App IDs/AppIDsViewController.swift b/AltStore/App IDs/AppIDsViewController.swift index 0fc8ceb1c..8030e6c9d 100644 --- a/AltStore/App IDs/AppIDsViewController.swift +++ b/AltStore/App IDs/AppIDsViewController.swift @@ -98,9 +98,6 @@ private extension AppIDsViewController formatter.allowedUnits = [.minute, .hour, .day] formatter.maximumUnitCount = 1 - formatter.unitsStyle = DateComponentsFormatter.UnitsStyle.abbreviated - - cell.bannerView.button.setTitle(formatter.string(from: Date(), to: expirationDate)?.uppercased(), for: .normal) formatter.includesTimeRemainingPhrase = true diff --git a/AltStore/My Apps/MyAppsViewController.swift b/AltStore/My Apps/MyAppsViewController.swift index 3da114f22..a5eac9acd 100644 --- a/AltStore/My Apps/MyAppsViewController.swift +++ b/AltStore/My Apps/MyAppsViewController.swift @@ -337,8 +337,6 @@ private extension MyAppsViewController formatter.allowedUnits = [.day, .hour, .minute] - formatter.unitsStyle = DateComponentsFormatter.UnitsStyle.abbreviated - formatter.maximumUnitCount = 1 From 95e00d81f5dde01b38e1fd966c77176ca733b120 Mon Sep 17 00:00:00 2001 From: Riley Testut Date: Tue, 7 Feb 2023 16:11:39 -0600 Subject: [PATCH 13/29] =?UTF-8?q?Adds=20=E2=80=9CClear=20Cache=E2=80=9D=20?= =?UTF-8?q?button=20to=20remove=20temporary=20files=20and=20uninstalled=20?= =?UTF-8?q?app=20backups?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (cherry picked from commit 3adfc9db6de2f8e05b1d7dee1bbe486493c961c0) --- AltStore.xcodeproj/project.pbxproj | 4 + AltStore/Managing Apps/AppManager.swift | 22 +- .../Operations/ClearAppCacheOperation.swift | 203 ++++++++++++++++++ .../Settings/SettingsViewController.swift | 42 ++++ 4 files changed, 265 insertions(+), 6 deletions(-) create mode 100644 AltStore/Operations/ClearAppCacheOperation.swift diff --git a/AltStore.xcodeproj/project.pbxproj b/AltStore.xcodeproj/project.pbxproj index 233463c55..41d03e405 100644 --- a/AltStore.xcodeproj/project.pbxproj +++ b/AltStore.xcodeproj/project.pbxproj @@ -332,6 +332,7 @@ D57FE84428C7DB7100216002 /* ErrorLogViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D57FE84328C7DB7100216002 /* ErrorLogViewController.swift */; }; D58916FE28C7C55C00E39C8B /* LoggedError.swift in Sources */ = {isa = PBXBuildFile; fileRef = D58916FD28C7C55C00E39C8B /* LoggedError.swift */; }; D593F1942717749A006E82DE /* PatchAppOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = D593F1932717749A006E82DE /* PatchAppOperation.swift */; }; + D5ACE84528E3B8450021CAB9 /* ClearAppCacheOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5ACE84428E3B8450021CAB9 /* ClearAppCacheOperation.swift */; }; D5CA0C4B280E141900469595 /* ManagedPatron.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5CA0C4A280E141900469595 /* ManagedPatron.swift */; }; D5CA0C4E280E249E00469595 /* AltStore9ToAltStore10.xcmappingmodel in Sources */ = {isa = PBXBuildFile; fileRef = D5CA0C4D280E249E00469595 /* AltStore9ToAltStore10.xcmappingmodel */; }; D5DAE0942804B0B80034D8D4 /* ScreenshotProcessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5DAE0932804B0B80034D8D4 /* ScreenshotProcessor.swift */; }; @@ -839,6 +840,7 @@ D57FE84328C7DB7100216002 /* ErrorLogViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ErrorLogViewController.swift; sourceTree = ""; }; D58916FD28C7C55C00E39C8B /* LoggedError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoggedError.swift; sourceTree = ""; }; D593F1932717749A006E82DE /* PatchAppOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PatchAppOperation.swift; sourceTree = ""; }; + D5ACE84428E3B8450021CAB9 /* ClearAppCacheOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClearAppCacheOperation.swift; sourceTree = ""; }; D5CA0C4A280E141900469595 /* ManagedPatron.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ManagedPatron.swift; sourceTree = ""; }; D5CA0C4C280E242500469595 /* AltStore 10.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "AltStore 10.xcdatamodel"; sourceTree = ""; }; D5CA0C4D280E249E00469595 /* AltStore9ToAltStore10.xcmappingmodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcmappingmodel; path = AltStore9ToAltStore10.xcmappingmodel; sourceTree = ""; }; @@ -1697,6 +1699,7 @@ D57F2C9026E0070200B9FA39 /* EnableJITOperation.swift */, D5DAE0952804DF430034D8D4 /* UpdatePatronsOperation.swift */, D5E1E7C028077DE90016FC96 /* FetchTrustedSourcesOperation.swift */, + D5ACE84428E3B8450021CAB9 /* ClearAppCacheOperation.swift */, BF7B44062725A4B8005288A4 /* Patch App */, ); path = Operations; @@ -2504,6 +2507,7 @@ BFD6B03322DFF20800B86064 /* MyAppsComponents.swift in Sources */, BF41B808233433C100C593A3 /* LoadingState.swift in Sources */, BFF0B69A2322D7D0007A79E1 /* UIScreen+CompactHeight.swift in Sources */, + D5ACE84528E3B8450021CAB9 /* ClearAppCacheOperation.swift in Sources */, D5F2F6A92720B7C20081CCF5 /* PatchViewController.swift in Sources */, B39F16132918D7C5002E9404 /* Consts.swift in Sources */, BF8F69C222E659F700049BA1 /* AppContentViewController.swift in Sources */, diff --git a/AltStore/Managing Apps/AppManager.swift b/AltStore/Managing Apps/AppManager.swift index 05e9c8d5c..d11aa7734 100644 --- a/AltStore/Managing Apps/AppManager.swift +++ b/AltStore/Managing Apps/AppManager.swift @@ -307,6 +307,16 @@ extension AppManager presentingViewController.present(alertController, animated: true, completion: nil) } } + + func clearAppCache(completion: @escaping (Result) -> Void) + { + let clearAppCacheOperation = ClearAppCacheOperation() + clearAppCacheOperation.resultHandler = { result in + completion(result) + } + + self.run([clearAppCacheOperation], context: nil) + } } extension AppManager @@ -754,6 +764,12 @@ extension AppManager let progress = self.refreshProgress[app.bundleIdentifier] return progress } + + func isActivelyManagingApp(withBundleID bundleID: String) -> Bool + { + let isActivelyManaging = self.installationProgress.keys.contains(bundleID) || self.refreshProgress.keys.contains(bundleID) + return isActivelyManaging + } } extension AppManager @@ -808,12 +824,6 @@ private extension AppManager } } - func isActivelyManagingApp(withBundleID bundleID: String) -> Bool - { - let isActivelyManaging = self.installationProgress.keys.contains(bundleID) || self.refreshProgress.keys.contains(bundleID) - return isActivelyManaging - } - @discardableResult private func perform(_ operations: [AppOperation], presentingViewController: UIViewController?, group: RefreshGroup) -> RefreshGroup { diff --git a/AltStore/Operations/ClearAppCacheOperation.swift b/AltStore/Operations/ClearAppCacheOperation.swift new file mode 100644 index 000000000..614dc75f8 --- /dev/null +++ b/AltStore/Operations/ClearAppCacheOperation.swift @@ -0,0 +1,203 @@ +// +// ClearAppCacheOperation.swift +// AltStore +// +// Created by Riley Testut on 9/27/22. +// Copyright © 2022 Riley Testut. All rights reserved. +// + +import Foundation +import AltStoreCore + +struct BatchError: ALTLocalizedError +{ + enum Code: Int, ALTErrorCode + { + typealias Error = BatchError + + case batchError + } + + var code: Code = .batchError + var underlyingErrors: [Error] + + var errorTitle: String? + var errorFailure: String? + + init(errors: [Error]) + { + self.underlyingErrors = errors + } + + var errorFailureReason: String { + guard !self.underlyingErrors.isEmpty else { return NSLocalizedString("An unknown error occured.", comment: "") } + + let errorMessages = self.underlyingErrors.map { $0.localizedDescription } + + let message = errorMessages.joined(separator: "\n\n") + return message + } +} + +@objc(ClearAppCacheOperation) +class ClearAppCacheOperation: ResultOperation +{ + private let coordinator = NSFileCoordinator() + private let coordinatorQueue = OperationQueue() + + override init() + { + self.coordinatorQueue.name = "AltStore - ClearAppCacheOperation Queue" + } + + override func main() + { + super.main() + + var allErrors = [Error]() + + self.clearTemporaryDirectory { result in + switch result + { + case .failure(let batchError as BatchError): allErrors.append(contentsOf: batchError.underlyingErrors) + case .failure(let error): allErrors.append(error) + case .success: break + } + + self.removeUninstalledAppBackupDirectories { result in + switch result + { + case .failure(let batchError as BatchError): allErrors.append(contentsOf: batchError.underlyingErrors) + case .failure(let error): allErrors.append(error) + case .success: break + } + + if allErrors.isEmpty + { + self.finish(.success(())) + } + else + { + let error = BatchError(errors: allErrors) + self.finish(.failure(error)) + } + } + } + } +} + +private extension ClearAppCacheOperation +{ + func clearTemporaryDirectory(completion: @escaping (Result) -> Void) + { + let intent = NSFileAccessIntent.writingIntent(with: FileManager.default.temporaryDirectory, options: [.forDeleting]) + self.coordinator.coordinate(with: [intent], queue: self.coordinatorQueue) { (error) in + do + { + if let error + { + throw error + } + + let fileURLs = try FileManager.default.contentsOfDirectory(at: intent.url, + includingPropertiesForKeys: [], + options: [.skipsSubdirectoryDescendants, .skipsHiddenFiles]) + var errors = [Error]() + + for fileURL in fileURLs + { + do + { + print("[ALTLog] Removing item from temporary directory:", fileURL.lastPathComponent) + try FileManager.default.removeItem(at: fileURL) + } + catch + { + print("[ALTLog] Failed to remove \(fileURL.lastPathComponent) from temporary directory.", error) + errors.append(error) + } + } + + if !errors.isEmpty + { + let error = BatchError(errors: errors) + completion(.failure(error)) + } + else + { + completion(.success(())) + } + } + catch + { + completion(.failure(error)) + } + } + } + + func removeUninstalledAppBackupDirectories(completion: @escaping (Result) -> Void) + { + guard let backupsDirectory = FileManager.default.appBackupsDirectory else { return completion(.failure(OperationError.missingAppGroup)) } + + DatabaseManager.shared.persistentContainer.performBackgroundTask { context in + let installedAppBundleIDs = Set(InstalledApp.all(in: context).map { $0.bundleIdentifier }) + + let intent = NSFileAccessIntent.writingIntent(with: backupsDirectory, options: [.forDeleting]) + self.coordinator.coordinate(with: [intent], queue: self.coordinatorQueue) { (error) in + do + { + if let error + { + throw error + } + + var isDirectory: ObjCBool = false + guard FileManager.default.fileExists(atPath: intent.url.path, isDirectory: &isDirectory), isDirectory.boolValue else { + completion(.success(())) + return + } + + let fileURLs = try FileManager.default.contentsOfDirectory(at: intent.url, + includingPropertiesForKeys: [.isDirectoryKey, .nameKey], + options: [.skipsSubdirectoryDescendants, .skipsHiddenFiles]) + var errors = [Error]() + + for backupDirectory in fileURLs + { + do + { + let resourceValues = try backupDirectory.resourceValues(forKeys: [.isDirectoryKey, .nameKey]) + guard let isDirectory = resourceValues.isDirectory, let bundleID = resourceValues.name else { continue } + + if isDirectory && !installedAppBundleIDs.contains(bundleID) && !AppManager.shared.isActivelyManagingApp(withBundleID: bundleID) + { + print("[ALTLog] Removing backup directory for uninstalled app:", bundleID) + try FileManager.default.removeItem(at: backupDirectory) + } + } + catch + { + print("[ALTLog] Failed to remove app backup directory:", error) + errors.append(error) + } + } + + if !errors.isEmpty + { + let error = BatchError(errors: errors) + completion(.failure(error)) + } + else + { + completion(.success(())) + } + } + catch + { + print("[ALTLog] Failed to remove app backup directory:", error) + completion(.failure(error)) + } + } + } + } +} diff --git a/AltStore/Settings/SettingsViewController.swift b/AltStore/Settings/SettingsViewController.swift index e43e21f4e..6293ef031 100644 --- a/AltStore/Settings/SettingsViewController.swift +++ b/AltStore/Settings/SettingsViewController.swift @@ -48,6 +48,12 @@ extension SettingsViewController case softwareLicenses } + fileprivate enum TechyThingsRow: Int, CaseIterable + { + case errorLog + case clearCache + } + fileprivate enum DebugRow: Int, CaseIterable { case sendFeedback @@ -291,6 +297,34 @@ private extension SettingsViewController self.present(viewController, animated: true, completion: nil) } + func clearCache() + { + let alertController = UIAlertController(title: NSLocalizedString("Are you sure you want to clear AltStore's cache?", comment: ""), + message: NSLocalizedString("This will remove all temporary files as well as backups for uninstalled apps.", comment: ""), + preferredStyle: .actionSheet) + alertController.addAction(UIAlertAction(title: UIAlertAction.cancel.title, style: UIAlertAction.cancel.style) { [weak self] _ in + self?.tableView.indexPathForSelectedRow.map { self?.tableView.deselectRow(at: $0, animated: true) } + }) + alertController.addAction(UIAlertAction(title: NSLocalizedString("Clear Cache", comment: ""), style: .destructive) { [weak self] _ in + AppManager.shared.clearAppCache { result in + DispatchQueue.main.async { + self?.tableView.indexPathForSelectedRow.map { self?.tableView.deselectRow(at: $0, animated: true) } + + switch result + { + case .success: break + case .failure(let error): + let alertController = UIAlertController(title: NSLocalizedString("Unable to Clear Cache", comment: ""), message: error.localizedDescription, preferredStyle: .alert) + alertController.addAction(.ok) + self?.present(alertController, animated: true) + } + } + } + }) + + self.present(alertController, animated: true) + } + @IBAction func handleDebugModeGesture(_ gestureRecognizer: UISwipeGestureRecognizer) { self.debugGestureCounter += 1 @@ -470,6 +504,14 @@ extension SettingsViewController self.addRefreshAppsShortcut() } + case .techyThings: + let row = TechyThingsRow.allCases[indexPath.row] + switch row + { + case .errorLog: break + case .clearCache: self.clearCache() + } + case .credits: let row = CreditsRow.allCases[indexPath.row] switch row From a95625a34a6ffdf7b83653b516c9544349b96e34 Mon Sep 17 00:00:00 2001 From: Riley Testut Date: Wed, 8 Feb 2023 13:50:29 -0600 Subject: [PATCH 14/29] =?UTF-8?q?Adds=20=E2=80=9CClear=20Cache=E2=80=9D=20?= =?UTF-8?q?description=20to=20Techy=20Things=20section=20footer?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (cherry picked from commit 913db5131be741a8d2f498b85a426ac2e43cf8c5) --- AltStore/Settings/SettingsViewController.swift | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/AltStore/Settings/SettingsViewController.swift b/AltStore/Settings/SettingsViewController.swift index 6293ef031..ba3bcebd0 100644 --- a/AltStore/Settings/SettingsViewController.swift +++ b/AltStore/Settings/SettingsViewController.swift @@ -211,6 +211,16 @@ private extension SettingsViewController case .instructions: break + case .techyThings: + if isHeader + { + settingsHeaderFooterView.primaryLabel.text = NSLocalizedString("TECHY THINGS", comment: "") + } + else + { + settingsHeaderFooterView.secondaryLabel.text = NSLocalizedString("Free up disk space by removing non-essential data, such as temporary files and backups for uninstalled apps.", comment: "") + } + case .credits: settingsHeaderFooterView.primaryLabel.text = NSLocalizedString("CREDITS", comment: "") @@ -445,7 +455,7 @@ extension SettingsViewController switch section { case .signIn where self.activeTeam != nil: return nil - case .signIn, .patreon, .appRefresh: + case .signIn, .patreon, .appRefresh, .techyThings, .macDirtyCow: let footerView = tableView.dequeueReusableHeaderFooterView(withIdentifier: "HeaderFooterView") as! SettingsHeaderFooterView self.prepare(footerView, for: section, isHeader: false) return footerView @@ -476,11 +486,11 @@ extension SettingsViewController { case .signIn where self.activeTeam != nil: return 1.0 case .account where self.activeTeam == nil: return 1.0 - case .signIn, .patreon, .appRefresh: + case .signIn, .patreon, .appRefresh, .techyThings, .macDirtyCow: let height = self.preferredHeight(for: self.prototypeHeaderFooterView, in: section, isHeader: false) return height - case .account, .credits, .debug, .instructions: return 0.0 + case .account, .credits, .debug, .instructions, .techyThings: return 0.0 } } } From 88ad828ce097ddf36ca610e22a1e74772673f8b4 Mon Sep 17 00:00:00 2001 From: Spidy123222 Date: Wed, 30 Aug 2023 03:29:50 +0000 Subject: [PATCH 15/29] hopefully fix error code build error --- AltStore/Operations/ClearAppCacheOperation.swift | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/AltStore/Operations/ClearAppCacheOperation.swift b/AltStore/Operations/ClearAppCacheOperation.swift index 614dc75f8..16b644e8d 100644 --- a/AltStore/Operations/ClearAppCacheOperation.swift +++ b/AltStore/Operations/ClearAppCacheOperation.swift @@ -11,13 +11,14 @@ import AltStoreCore struct BatchError: ALTLocalizedError { + /* enum Code: Int, ALTErrorCode { typealias Error = BatchError case batchError } - + */ var code: Code = .batchError var underlyingErrors: [Error] From 357d85a72e255f2f986ee4dcc36a21e967f3a1d1 Mon Sep 17 00:00:00 2001 From: Spidy123222 Date: Wed, 30 Aug 2023 03:39:47 +0000 Subject: [PATCH 16/29] please o riley build --- AltStore/Operations/ClearAppCacheOperation.swift | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/AltStore/Operations/ClearAppCacheOperation.swift b/AltStore/Operations/ClearAppCacheOperation.swift index 16b644e8d..41d00c8bc 100644 --- a/AltStore/Operations/ClearAppCacheOperation.swift +++ b/AltStore/Operations/ClearAppCacheOperation.swift @@ -8,17 +8,17 @@ import Foundation import AltStoreCore - +/* struct BatchError: ALTLocalizedError { - /* + enum Code: Int, ALTErrorCode { typealias Error = BatchError case batchError } - */ + var code: Code = .batchError var underlyingErrors: [Error] @@ -39,7 +39,7 @@ struct BatchError: ALTLocalizedError return message } } - +*/ @objc(ClearAppCacheOperation) class ClearAppCacheOperation: ResultOperation { @@ -60,7 +60,7 @@ class ClearAppCacheOperation: ResultOperation self.clearTemporaryDirectory { result in switch result { - case .failure(let batchError as BatchError): allErrors.append(contentsOf: batchError.underlyingErrors) + //case .failure(let batchError as BatchError): allErrors.append(contentsOf: batchError.underlyingErrors) case .failure(let error): allErrors.append(error) case .success: break } @@ -68,7 +68,7 @@ class ClearAppCacheOperation: ResultOperation self.removeUninstalledAppBackupDirectories { result in switch result { - case .failure(let batchError as BatchError): allErrors.append(contentsOf: batchError.underlyingErrors) + //case .failure(let batchError as BatchError): allErrors.append(contentsOf: batchError.underlyingErrors) case .failure(let error): allErrors.append(error) case .success: break } From 9c67c237eea1ab0c37f9f8d69a1d327e9f70f957 Mon Sep 17 00:00:00 2001 From: Spidy123222 Date: Wed, 30 Aug 2023 03:52:32 +0000 Subject: [PATCH 17/29] get rest of batcherror --- AltStore/Operations/ClearAppCacheOperation.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/AltStore/Operations/ClearAppCacheOperation.swift b/AltStore/Operations/ClearAppCacheOperation.swift index 41d00c8bc..852bb1887 100644 --- a/AltStore/Operations/ClearAppCacheOperation.swift +++ b/AltStore/Operations/ClearAppCacheOperation.swift @@ -79,7 +79,7 @@ class ClearAppCacheOperation: ResultOperation } else { - let error = BatchError(errors: allErrors) + //let error = BatchError(errors: allErrors) self.finish(.failure(error)) } } @@ -121,7 +121,7 @@ private extension ClearAppCacheOperation if !errors.isEmpty { - let error = BatchError(errors: errors) + //let error = BatchError(errors: errors) completion(.failure(error)) } else @@ -185,7 +185,7 @@ private extension ClearAppCacheOperation if !errors.isEmpty { - let error = BatchError(errors: errors) + //let error = BatchError(errors: errors) completion(.failure(error)) } else From 580db6530e73cb4a186bf34a36069ce3d3b190fa Mon Sep 17 00:00:00 2001 From: Spidy123222 Date: Wed, 30 Aug 2023 04:26:41 +0000 Subject: [PATCH 18/29] fix the mighty error --- .../Operations/ClearAppCacheOperation.swift | 6 ++-- .../Settings/SettingsViewController.swift | 31 +++---------------- 2 files changed, 8 insertions(+), 29 deletions(-) diff --git a/AltStore/Operations/ClearAppCacheOperation.swift b/AltStore/Operations/ClearAppCacheOperation.swift index 852bb1887..ebe52acc4 100644 --- a/AltStore/Operations/ClearAppCacheOperation.swift +++ b/AltStore/Operations/ClearAppCacheOperation.swift @@ -80,7 +80,7 @@ class ClearAppCacheOperation: ResultOperation else { //let error = BatchError(errors: allErrors) - self.finish(.failure(error)) + //self.finish(.failure(error)) } } } @@ -122,7 +122,7 @@ private extension ClearAppCacheOperation if !errors.isEmpty { //let error = BatchError(errors: errors) - completion(.failure(error)) + //completion(.failure(error)) } else { @@ -186,7 +186,7 @@ private extension ClearAppCacheOperation if !errors.isEmpty { //let error = BatchError(errors: errors) - completion(.failure(error)) + //completion(.failure(error)) } else { diff --git a/AltStore/Settings/SettingsViewController.swift b/AltStore/Settings/SettingsViewController.swift index ba3bcebd0..bd88d4eb1 100644 --- a/AltStore/Settings/SettingsViewController.swift +++ b/AltStore/Settings/SettingsViewController.swift @@ -48,16 +48,11 @@ extension SettingsViewController case softwareLicenses } - fileprivate enum TechyThingsRow: Int, CaseIterable - { - case errorLog - case clearCache - } - fileprivate enum DebugRow: Int, CaseIterable { case sendFeedback case refreshAttempts + case clearCache case errorLog case resetPairingFile case resetAdiPb @@ -211,16 +206,6 @@ private extension SettingsViewController case .instructions: break - case .techyThings: - if isHeader - { - settingsHeaderFooterView.primaryLabel.text = NSLocalizedString("TECHY THINGS", comment: "") - } - else - { - settingsHeaderFooterView.secondaryLabel.text = NSLocalizedString("Free up disk space by removing non-essential data, such as temporary files and backups for uninstalled apps.", comment: "") - } - case .credits: settingsHeaderFooterView.primaryLabel.text = NSLocalizedString("CREDITS", comment: "") @@ -455,7 +440,7 @@ extension SettingsViewController switch section { case .signIn where self.activeTeam != nil: return nil - case .signIn, .patreon, .appRefresh, .techyThings, .macDirtyCow: + case .signIn, .patreon, .appRefresh: let footerView = tableView.dequeueReusableHeaderFooterView(withIdentifier: "HeaderFooterView") as! SettingsHeaderFooterView self.prepare(footerView, for: section, isHeader: false) return footerView @@ -486,11 +471,11 @@ extension SettingsViewController { case .signIn where self.activeTeam != nil: return 1.0 case .account where self.activeTeam == nil: return 1.0 - case .signIn, .patreon, .appRefresh, .techyThings, .macDirtyCow: + case .signIn, .patreon, .appRefresh: let height = self.preferredHeight(for: self.prototypeHeaderFooterView, in: section, isHeader: false) return height - case .account, .credits, .debug, .instructions, .techyThings: return 0.0 + case .account, .credits, .debug, .instructions: return 0.0 } } } @@ -514,13 +499,6 @@ extension SettingsViewController self.addRefreshAppsShortcut() } - case .techyThings: - let row = TechyThingsRow.allCases[indexPath.row] - switch row - { - case .errorLog: break - case .clearCache: self.clearCache() - } case .credits: let row = CreditsRow.allCases[indexPath.row] @@ -611,6 +589,7 @@ extension SettingsViewController ELOG("UIApplication.openSettingsURLString invalid") } case .refreshAttempts, .errorLog: break + case .clearCache: self.clearCache() } default: break From 12fc6cf6e2e47b95d830edee85886c75db68579a Mon Sep 17 00:00:00 2001 From: Spidy123222 Date: Wed, 30 Aug 2023 04:47:36 +0000 Subject: [PATCH 19/29] attempt fix settings --- AltStore/Settings/SettingsViewController.swift | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/AltStore/Settings/SettingsViewController.swift b/AltStore/Settings/SettingsViewController.swift index bd88d4eb1..9b96f71d4 100644 --- a/AltStore/Settings/SettingsViewController.swift +++ b/AltStore/Settings/SettingsViewController.swift @@ -537,6 +537,9 @@ extension SettingsViewController let toastView = ToastView(text: NSLocalizedString("Cannot Send Mail", comment: ""), detailText: nil) toastView.show(in: self) } + + case .clearCache: self.clearCache() + case .resetPairingFile: let filename = "ALTPairingFile.mobiledevicepairing" let fm = FileManager.default @@ -589,7 +592,7 @@ extension SettingsViewController ELOG("UIApplication.openSettingsURLString invalid") } case .refreshAttempts, .errorLog: break - case .clearCache: self.clearCache() + } default: break From a759c7be9ef08b70d7bb765d74c9f3968ead3c12 Mon Sep 17 00:00:00 2001 From: Spidy123222 Date: Wed, 30 Aug 2023 05:12:02 +0000 Subject: [PATCH 20/29] please fix to show button --- AltStore/Settings/SettingsViewController.swift | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/AltStore/Settings/SettingsViewController.swift b/AltStore/Settings/SettingsViewController.swift index 9b96f71d4..27048e749 100644 --- a/AltStore/Settings/SettingsViewController.swift +++ b/AltStore/Settings/SettingsViewController.swift @@ -52,11 +52,11 @@ extension SettingsViewController { case sendFeedback case refreshAttempts - case clearCache case errorLog case resetPairingFile case resetAdiPb case advancedSettings + case clearCache } } @@ -294,7 +294,7 @@ private extension SettingsViewController func clearCache() { - let alertController = UIAlertController(title: NSLocalizedString("Are you sure you want to clear AltStore's cache?", comment: ""), + let alertController = UIAlertController(title: NSLocalizedString("Are you sure you want to clear SideStore's cache?", comment: ""), message: NSLocalizedString("This will remove all temporary files as well as backups for uninstalled apps.", comment: ""), preferredStyle: .actionSheet) alertController.addAction(UIAlertAction(title: UIAlertAction.cancel.title, style: UIAlertAction.cancel.style) { [weak self] _ in @@ -537,8 +537,6 @@ extension SettingsViewController let toastView = ToastView(text: NSLocalizedString("Cannot Send Mail", comment: ""), detailText: nil) toastView.show(in: self) } - - case .clearCache: self.clearCache() case .resetPairingFile: let filename = "ALTPairingFile.mobiledevicepairing" @@ -592,6 +590,7 @@ extension SettingsViewController ELOG("UIApplication.openSettingsURLString invalid") } case .refreshAttempts, .errorLog: break + case .clearCache: self.clearCache() } From 3859e98801e57bc832d18ca34d62e7dab7be98f4 Mon Sep 17 00:00:00 2001 From: Spidy123222 Date: Wed, 30 Aug 2023 05:30:25 +0000 Subject: [PATCH 21/29] =?UTF-8?q?Add=20button=20to=20storyboard=20?= =?UTF-8?q?=F0=9F=99=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AltStore/Settings/Settings.storyboard | 28 +++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/AltStore/Settings/Settings.storyboard b/AltStore/Settings/Settings.storyboard index 315b9086e..4ea58acd3 100644 --- a/AltStore/Settings/Settings.storyboard +++ b/AltStore/Settings/Settings.storyboard @@ -684,6 +684,34 @@ + + + + + + + + + + + + + + + + + + + + + + + From 8508fe79b59d507248e9ca30e7c5e07854c11c44 Mon Sep 17 00:00:00 2001 From: Spidy123222 Date: Wed, 30 Aug 2023 07:09:52 +0000 Subject: [PATCH 22/29] change order of settings debug section --- AltStore/Settings/Settings.storyboard | 56 +++++++++---------- .../Settings/SettingsViewController.swift | 3 +- 2 files changed, 30 insertions(+), 29 deletions(-) diff --git a/AltStore/Settings/Settings.storyboard b/AltStore/Settings/Settings.storyboard index 4ea58acd3..be7d6c157 100644 --- a/AltStore/Settings/Settings.storyboard +++ b/AltStore/Settings/Settings.storyboard @@ -549,6 +549,34 @@ + + + + + + + + + + + + + + + + + + + + + + + @@ -684,34 +712,6 @@ - - - - - - - - - - - - - - - - - - - - - - - diff --git a/AltStore/Settings/SettingsViewController.swift b/AltStore/Settings/SettingsViewController.swift index 27048e749..45cc63b9c 100644 --- a/AltStore/Settings/SettingsViewController.swift +++ b/AltStore/Settings/SettingsViewController.swift @@ -537,6 +537,8 @@ extension SettingsViewController let toastView = ToastView(text: NSLocalizedString("Cannot Send Mail", comment: ""), detailText: nil) toastView.show(in: self) } + + case .clearCache: self.clearCache() case .resetPairingFile: let filename = "ALTPairingFile.mobiledevicepairing" @@ -590,7 +592,6 @@ extension SettingsViewController ELOG("UIApplication.openSettingsURLString invalid") } case .refreshAttempts, .errorLog: break - case .clearCache: self.clearCache() } From 8a5c31b81d3504e048b7dc89b781d1d23733e4e8 Mon Sep 17 00:00:00 2001 From: Spidy123222 Date: Wed, 30 Aug 2023 07:23:56 +0000 Subject: [PATCH 23/29] make button function again --- AltStore/Settings/SettingsViewController.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AltStore/Settings/SettingsViewController.swift b/AltStore/Settings/SettingsViewController.swift index 45cc63b9c..075960e7b 100644 --- a/AltStore/Settings/SettingsViewController.swift +++ b/AltStore/Settings/SettingsViewController.swift @@ -592,7 +592,7 @@ extension SettingsViewController ELOG("UIApplication.openSettingsURLString invalid") } case .refreshAttempts, .errorLog: break - + case .clearCache: self.clearCache() } default: break From 970ab38b27324a060cfccc5ee9008064245aa310 Mon Sep 17 00:00:00 2001 From: Spidy123222 Date: Wed, 30 Aug 2023 07:24:27 +0000 Subject: [PATCH 24/29] move debug row --- AltStore/Settings/SettingsViewController.swift | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/AltStore/Settings/SettingsViewController.swift b/AltStore/Settings/SettingsViewController.swift index 075960e7b..f8f89c61e 100644 --- a/AltStore/Settings/SettingsViewController.swift +++ b/AltStore/Settings/SettingsViewController.swift @@ -52,11 +52,12 @@ extension SettingsViewController { case sendFeedback case refreshAttempts + case clearCache case errorLog case resetPairingFile case resetAdiPb case advancedSettings - case clearCache + } } @@ -592,7 +593,7 @@ extension SettingsViewController ELOG("UIApplication.openSettingsURLString invalid") } case .refreshAttempts, .errorLog: break - case .clearCache: self.clearCache() + } default: break From c81236957b19ae33fea4251ddfc046cd27e45ead Mon Sep 17 00:00:00 2001 From: June Park Date: Sat, 25 Nov 2023 15:11:22 +0900 Subject: [PATCH 25/29] bugfix(settings): fix rounding issues on clear cache button (#536) --- AltStore/Settings/Settings.storyboard | 95 ++++++++++--------- .../Settings/SettingsViewController.swift | 2 +- 2 files changed, 51 insertions(+), 46 deletions(-) diff --git a/AltStore/Settings/Settings.storyboard b/AltStore/Settings/Settings.storyboard index be7d6c157..19910bd9d 100644 --- a/AltStore/Settings/Settings.storyboard +++ b/AltStore/Settings/Settings.storyboard @@ -21,7 +21,7 @@ - - - - + - @@ -647,19 +652,19 @@ - + - @@ -680,19 +685,19 @@ - + - diff --git a/AltStore/Settings/SettingsViewController.swift b/AltStore/Settings/SettingsViewController.swift index f8f89c61e..4d5b52a54 100644 --- a/AltStore/Settings/SettingsViewController.swift +++ b/AltStore/Settings/SettingsViewController.swift @@ -52,8 +52,8 @@ extension SettingsViewController { case sendFeedback case refreshAttempts - case clearCache case errorLog + case clearCache case resetPairingFile case resetAdiPb case advancedSettings From 5f0015fad036ee988b0ee6032b07f5695ac78fe5 Mon Sep 17 00:00:00 2001 From: junepark678 <40409848+junepark678@users.noreply.github.com> Date: Sun, 26 Nov 2023 13:50:45 +0900 Subject: [PATCH 26/29] chore(Clear Cache): do proper error handling --- .../Operations/ClearAppCacheOperation.swift | 16 ++++--- AltStore/Operations/OperationError.swift | 3 ++ AltStore/Settings/Settings.storyboard | 48 +++++++++---------- .../Settings/SettingsViewController.swift | 5 ++ 4 files changed, 42 insertions(+), 30 deletions(-) diff --git a/AltStore/Operations/ClearAppCacheOperation.swift b/AltStore/Operations/ClearAppCacheOperation.swift index ebe52acc4..879858c14 100644 --- a/AltStore/Operations/ClearAppCacheOperation.swift +++ b/AltStore/Operations/ClearAppCacheOperation.swift @@ -79,8 +79,9 @@ class ClearAppCacheOperation: ResultOperation } else { - //let error = BatchError(errors: allErrors) - //self.finish(.failure(error)) + self.finish(.failure(OperationError.cacheClearError(errors: allErrors.map({ error in + return error.localizedDescription + })))) } } } @@ -121,8 +122,9 @@ private extension ClearAppCacheOperation if !errors.isEmpty { - //let error = BatchError(errors: errors) - //completion(.failure(error)) + completion(.failure(OperationError.cacheClearError(errors: errors.map({ error in + return error.localizedDescription + })))) } else { @@ -163,6 +165,7 @@ private extension ClearAppCacheOperation options: [.skipsSubdirectoryDescendants, .skipsHiddenFiles]) var errors = [Error]() + for backupDirectory in fileURLs { do @@ -185,8 +188,9 @@ private extension ClearAppCacheOperation if !errors.isEmpty { - //let error = BatchError(errors: errors) - //completion(.failure(error)) + completion(.failure(OperationError.cacheClearError(errors: errors.map({ error in + return error.localizedDescription + })))) } else { diff --git a/AltStore/Operations/OperationError.swift b/AltStore/Operations/OperationError.swift index 95cd1d288..4f33f6edd 100644 --- a/AltStore/Operations/OperationError.swift +++ b/AltStore/Operations/OperationError.swift @@ -40,6 +40,8 @@ enum OperationError: LocalizedError case provisioningError(result: String, message: String?) case anisetteV3Error(message: String) + case cacheClearError(errors: [String]) + var failureReason: String? { switch self { case .unknown: return NSLocalizedString("An unknown error occured.", comment: "") @@ -60,6 +62,7 @@ enum OperationError: LocalizedError case .anisetteV1Error(let message): return String(format: NSLocalizedString("An error occurred when getting anisette data from a V1 server: %@. Try using another anisette server.", comment: ""), message) case .provisioningError(let result, let message): return String(format: NSLocalizedString("An error occurred when provisioning: %@%@. Please try again. If the issue persists, report it on GitHub Issues!", comment: ""), result, message != nil ? (" (" + message! + ")") : "") case .anisetteV3Error(let message): return String(format: NSLocalizedString("An error occurred when getting anisette data from a V3 server: %@. Please try again. If the issue persists, report it on GitHub Issues!", comment: ""), message) + case .cacheClearError(let errors): return String(format: NSLocalizedString("An error occurred while clearing cache: %@", comment: ""), errors.joined(separator: "\n")) } } diff --git a/AltStore/Settings/Settings.storyboard b/AltStore/Settings/Settings.storyboard index 19910bd9d..199d839c3 100644 --- a/AltStore/Settings/Settings.storyboard +++ b/AltStore/Settings/Settings.storyboard @@ -359,22 +359,22 @@ -