From f542a52bda38ed754a936bd8b15ec9ccbb924929 Mon Sep 17 00:00:00 2001 From: Magesh K <47920326+mahee96@users.noreply.github.com> Date: Sat, 14 Dec 2024 05:51:11 +0530 Subject: [PATCH] [AltBackup+Schemes]: Fixes for URL schemes throughout both AltBackup and SideStore apps --- AltBackup/AppDelegate.swift | 18 +++++++-- AltBackup/BackupController.swift | 4 +- AltBackup/Info.plist | 4 +- AltBackup/ViewController.swift | 40 +++++++++++-------- AltStore/Info.plist | 19 +++------ AltStore/Managing Apps/AppManager.swift | 4 +- AltStore/Operations/BackupAppOperation.swift | 4 +- .../FileManager+SharedDirectories.swift | 4 +- AltStoreCore/Model/InstalledApp.swift | 8 +++- AltWidget/Info.plist | 1 - 10 files changed, 62 insertions(+), 44 deletions(-) diff --git a/AltBackup/AppDelegate.swift b/AltBackup/AppDelegate.swift index f6fa628e..2c88d4e8 100644 --- a/AltBackup/AppDelegate.swift +++ b/AltBackup/AppDelegate.swift @@ -88,14 +88,25 @@ private extension AppDelegate @objc func operationDidFinish(_ notification: Notification) { - defer { self.currentBackupReturnURL = nil } + defer { + self.currentBackupReturnURL = nil + } + // TODO: @mahee96: This doesn't account cases where backup is too long and user switched to other apps + // The check for self.currentBackupReturnURL when backup/restore was still in progress but app switched + // between FG/BG is improper, since it will ignore(eat up) the response(success/failure) to parent + // + // This leaves the backup/restore to show dummy animation forever guard let returnURL = self.currentBackupReturnURL, let result = notification.userInfo?[AppDelegate.operationResultKey] as? Result - else { return } + else { + return // This is bad (Needs fixing - never eat up response like this unless there is no context to post response to!) + } - guard var components = URLComponents(url: returnURL, resolvingAgainstBaseURL: false) else { return } + guard var components = URLComponents(url: returnURL, resolvingAgainstBaseURL: false) else { + return // This is ASSERTION Failure, ie RETURN URL needs to be valid. So ignoring (eating up) response is not the solution + } switch result { @@ -112,6 +123,7 @@ private extension AppDelegate guard let responseURL = components.url else { return } DispatchQueue.main.async { + // Response to the caller/parent app is posted here (url is provided by caller in incoming query params) UIApplication.shared.open(responseURL, options: [:]) { (success) in print("Sent response to app with success:", success) } diff --git a/AltBackup/BackupController.swift b/AltBackup/BackupController.swift index 98988d50..b34a27d9 100755 --- a/AltBackup/BackupController.swift +++ b/AltBackup/BackupController.swift @@ -131,7 +131,9 @@ class BackupController: NSObject guard let altstoreAppGroup = Bundle.main.altstoreAppGroup, let sharedDirectoryURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: altstoreAppGroup) - else { throw BackupError(.appGroupNotFound(nil), description: NSLocalizedString("Unable to create backup directory.", comment: "")) } + else { + throw BackupError(.appGroupNotFound(nil), description: NSLocalizedString("Unable to create backup directory.", comment: "")) + } let backupsDirectory = sharedDirectoryURL.appendingPathComponent("Backups") diff --git a/AltBackup/Info.plist b/AltBackup/Info.plist index de9d0f78..f7bbedb6 100644 --- a/AltBackup/Info.plist +++ b/AltBackup/Info.plist @@ -28,10 +28,10 @@ CFBundleTypeRole Editor CFBundleURLName - AltBackup General + SideBackup General CFBundleURLSchemes - altbackup + sidebackup diff --git a/AltBackup/ViewController.swift b/AltBackup/ViewController.swift index 17a819a5..eca547bb 100644 --- a/AltBackup/ViewController.swift +++ b/AltBackup/ViewController.swift @@ -82,23 +82,25 @@ class ViewController: UIViewController self.activityIndicatorView.color = .altstoreText self.activityIndicatorView.startAnimating() - #if DEBUG - let button1 = UIButton(type: .system) - button1.setTitle("Backup", for: .normal) - button1.setTitleColor(.white, for: .normal) - button1.titleLabel?.font = UIFont.preferredFont(forTextStyle: .body) - button1.addTarget(self, action: #selector(ViewController.backup), for: .primaryActionTriggered) - - let button2 = UIButton(type: .system) - button2.setTitle("Restore", for: .normal) - button2.setTitleColor(.white, for: .normal) - button2.titleLabel?.font = UIFont.preferredFont(forTextStyle: .body) - button2.addTarget(self, action: #selector(ViewController.restore), for: .primaryActionTriggered) - - let arrangedSubviews = [self.textLabel!, self.detailTextLabel!, self.activityIndicatorView!, button1, button2] - #else + // TODO: @mahee96: Disabled this buttons which were present for debugging purpose. + // Can find something useful for these later, but these are not required by this backup/restore app +// #if DEBUG +// let button1 = UIButton(type: .system) +// button1.setTitle("Backup", for: .normal) +// button1.setTitleColor(.white, for: .normal) +// button1.titleLabel?.font = UIFont.preferredFont(forTextStyle: .body) +// button1.addTarget(self, action: #selector(ViewController.backup), for: .primaryActionTriggered) +// +// let button2 = UIButton(type: .system) +// button2.setTitle("Restore", for: .normal) +// button2.setTitleColor(.white, for: .normal) +// button2.titleLabel?.font = UIFont.preferredFont(forTextStyle: .body) +// button2.addTarget(self, action: #selector(ViewController.restore), for: .primaryActionTriggered) +// +// let arrangedSubviews = [self.textLabel!, self.detailTextLabel!, self.activityIndicatorView!, button1, button2] +// #else let arrangedSubviews = [self.textLabel!, self.detailTextLabel!, self.activityIndicatorView!] - #endif +// #endif let stackView = UIStackView(arrangedSubviews: arrangedSubviews) stackView.translatesAutoresizingMaskIntoConstraints = false @@ -155,7 +157,8 @@ private extension ViewController self.textLabel.text = NSLocalizedString("Restoring app data…", comment: "") self.detailTextLabel.isHidden = true self.activityIndicatorView.startAnimating() - + + // TODO: @mahee96: This is pointless since, app going in bg/fg should still report its last operation properly case .none: self.textLabel.text = String(format: NSLocalizedString("%@ is inactive.", comment: ""), Bundle.main.appName ?? NSLocalizedString("App", comment: "")) @@ -198,6 +201,9 @@ private extension ViewController } } + // TODO: @mahee96: This doesn't account cases where backup is too long and user switched to other apps + // Now the user has lost his progress since current operation was cancelled due to switch between FG and BG + // if this just the reset for enum such that UI stops showing progress circle, then this is fine! @objc func didEnterBackground(_ notification: Notification) { // Reset UI once we've left app (but not before). diff --git a/AltStore/Info.plist b/AltStore/Info.plist index ef06a856..a2d64e77 100644 --- a/AltStore/Info.plist +++ b/AltStore/Info.plist @@ -7,7 +7,6 @@ ALTAppGroups group.$(APP_GROUP_IDENTIFIER) - group.com.SideStore.SideStore ALTDeviceID 00008120-001270DA119B401E @@ -63,10 +62,9 @@ CFBundleTypeRole Editor CFBundleURLName - AltStore General + SideStore General CFBundleURLSchemes - altstore sidestore @@ -74,10 +72,9 @@ CFBundleTypeRole Editor CFBundleURLName - AltStore Backup + SideStore Backup CFBundleURLSchemes - altstore-com.rileytestut.AltStore sidestore-com.SideStore.SideStore @@ -91,14 +88,8 @@ LSApplicationQueriesSchemes - altstore-com.rileytestut.AltStore - altstore-com.rileytestut.AltStore.Beta - altstore-com.rileytestut.Delta - altstore-com.rileytestut.Delta.Beta - altstore-com.rileytestut.Delta.Lite - altstore-com.rileytestut.Delta.Lite.Beta - altstore-com.rileytestut.Clip - altstore-com.rileytestut.Clip.Beta + sidestore-com.SideStore.SideStore + sidestore-com.SideStore.SideStore.Beta LSRequiresIPhoneOS @@ -122,7 +113,7 @@ OSLogPreferences - com.rileytestut.AltStore + com.SideStore.SideStore AltJIT diff --git a/AltStore/Managing Apps/AppManager.swift b/AltStore/Managing Apps/AppManager.swift index 56f0d05b..4c9d0dfb 100644 --- a/AltStore/Managing Apps/AppManager.swift +++ b/AltStore/Managing Apps/AppManager.swift @@ -28,8 +28,8 @@ extension AppManager static let didRemoveSourceNotification = Notification.Name("io.sidestore.AppManager.didRemoveSource") static let willInstallAppFromNewSourceNotification = Notification.Name("io.sidestore.AppManager.willInstallAppFromNewSource") - static let expirationWarningNotificationID = "altstore-expiration-warning" - static let enableJITResultNotificationID = "altstore-enable-jit" + static let expirationWarningNotificationID = "sidestore-expiration-warning" + static let enableJITResultNotificationID = "sidestore-enable-jit" } @available(iOS 13, *) diff --git a/AltStore/Operations/BackupAppOperation.swift b/AltStore/Operations/BackupAppOperation.swift index 3b7ab347..336a956d 100644 --- a/AltStore/Operations/BackupAppOperation.swift +++ b/AltStore/Operations/BackupAppOperation.swift @@ -162,7 +162,9 @@ private extension BackupAppOperation self?.applicationWillReturnObserver.map { NotificationCenter.default.removeObserver($0) } } - guard let self = self, !self.isFinished else { return } + guard let self = self, !self.isFinished else { + return + } self.timeoutTimer = Timer.scheduledTimer(withTimeInterval: 5, repeats: false) { [weak self] (timer) in // Final delay to ensure we don't prematurely return failure diff --git a/AltStoreCore/Extensions/FileManager+SharedDirectories.swift b/AltStoreCore/Extensions/FileManager+SharedDirectories.swift index c54e6a82..db0ec35b 100644 --- a/AltStoreCore/Extensions/FileManager+SharedDirectories.swift +++ b/AltStoreCore/Extensions/FileManager+SharedDirectories.swift @@ -11,7 +11,9 @@ import Foundation public extension FileManager { var altstoreSharedDirectory: URL? { - guard let appGroup = Bundle.main.altstoreAppGroup else { return nil } + guard let appGroup = Bundle.main.altstoreAppGroup else { + return nil + } let sharedDirectoryURL = self.containerURL(forSecurityApplicationGroupIdentifier: appGroup) return sharedDirectoryURL diff --git a/AltStoreCore/Model/InstalledApp.swift b/AltStoreCore/Model/InstalledApp.swift index 4f64309c..60f67ce6 100644 --- a/AltStoreCore/Model/InstalledApp.swift +++ b/AltStoreCore/Model/InstalledApp.swift @@ -343,14 +343,18 @@ public extension InstalledApp public extension InstalledApp { + // TODO: @mahee96: Do NOT hardcode app's url scheme prefixes as in here + // Need to get it dynamically from the Info.plist of other means var openAppURL: URL { - let openAppURL = URL(string: "altstore-" + self.bundleIdentifier + "://")! + let openAppURL = URL(string: "sidestore-" + self.bundleIdentifier + "://")! return openAppURL } + // TODO: @mahee96: Do NOT hardcode app's url scheme prefixes as in here + // Need to get it dynamically from the Info.plist of other means class func openAppURL(for app: AppProtocol) -> URL { - let openAppURL = URL(string: "altstore-" + app.bundleIdentifier + "://")! + let openAppURL = URL(string: "sidestore-" + app.bundleIdentifier + "://")! return openAppURL } diff --git a/AltWidget/Info.plist b/AltWidget/Info.plist index 187bc11c..268dcc6b 100644 --- a/AltWidget/Info.plist +++ b/AltWidget/Info.plist @@ -5,7 +5,6 @@ ALTAppGroups group.$(APP_GROUP_IDENTIFIER) - group.com.SideStore.SideStore CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE)