From 7ed45c7cb1bf4a077f762f106f79b4230e3f8b56 Mon Sep 17 00:00:00 2001 From: CelloSerenity <195480169+CelloSerenity@users.noreply.github.com> Date: Fri, 10 Oct 2025 14:53:39 -0600 Subject: [PATCH 1/6] Update error messages for clarity and detail Signed-off-by: CelloSerenity <195480169+CelloSerenity@users.noreply.github.com> --- AltStore/Operations/Errors/OperationError.swift | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/AltStore/Operations/Errors/OperationError.swift b/AltStore/Operations/Errors/OperationError.swift index fdd336dd..40f2dcee 100644 --- a/AltStore/Operations/Errors/OperationError.swift +++ b/AltStore/Operations/Errors/OperationError.swift @@ -221,9 +221,9 @@ struct OperationError: ALTLocalizedError { let appName = self.appName ?? NSLocalizedString("The app", comment: "") return String(format: NSLocalizedString("SideStore was denied permission to launch %@.", comment: ""), appName) case .noWiFi: return NSLocalizedString("You do not appear to be connected to Wi-Fi and/or StosVPN!\nSideStore will never be able to install or refresh applications without Wi-Fi and StosVPN.", comment: "") - case .tooNewError: return NSLocalizedString("iOS 17 has changed how JIT is enabled, therefore, SideStore cannot enable JIT without SideJITServer, StikDebug, or SideStore-nightly at this time, sorry for any inconvenience.", comment: "") + case .tooNewError: return NSLocalizedString("iOS 17.0-17.3.1 changed how JIT is enabled so SideStore cannot enable JIT without SideJITServer on these versions, sorry for any inconvenience.", comment: "") case .unableToConnectSideJIT: return NSLocalizedString("Unable to connect to SideJITServer. Please check that you are on the same Wi-Fi of and your Firewall has been set correctly on your server", comment: "") - case .unableToRespondSideJITDevice: return NSLocalizedString("SideJITServer is unable to connect to your iDevice. Please make sure you have paired your Device by running 'SideJITServer -y', or try refreshing SideJITServer from Settings", comment: "") + case .unableToRespondSideJITDevice: return NSLocalizedString("SideJITServer is unable to connect to your iDevice. Please make sure you have paired your iDevice by running 'SideJITServer -y', or try refreshing SideJITServer from Settings", comment: "") case .wrongSideJITIP: return NSLocalizedString("Incorrect SideJITServer IP. Please make sure that you are on the same Wi-Fi as SideJITServer", comment: "") case .refreshsidejit: return NSLocalizedString("Unable to find app; Please try refreshing SideJITServer from Settings", comment: "") case .anisetteV1Error: return NSLocalizedString("An error occurred while getting anisette data from a V1 server: %@. Try using another anisette server.", comment: "") @@ -310,7 +310,7 @@ extension MinimuxerError: LocalizedError { case .NoConnection: return NSLocalizedString("Unable to connect to the device, make sure StosVPN is enabled and you're connected to Wi-Fi. This could mean an invalid pairing.", comment: "") case .PairingFile: - return NSLocalizedString("Invalid pairing file. Your pairing file either didn't have a UDID, or it wasn't a valid plist. Please use idevice_pair to regenerate it", comment: "") + return NSLocalizedString("Invalid pairing file. Your pairing file either didn't have a UDID, or it wasn't a valid plist. Please use idevice_pair to recreate it.", comment: "") case .CreateDebug: return self.createService(name: "debug") @@ -338,7 +338,7 @@ extension MinimuxerError: LocalizedError { case .CreateAfc: return self.createService(name: "AFC") case .RwAfc: - return NSLocalizedString("AFC was unable to manage files on the device. This usually means an invalid pairing.", comment: "") + return NSLocalizedString("AFC was unable to manage files on the device. Ensure Wi-Fi is enabled and StosVPN is connected. If they are, recreate your pairing using idevice_pair.", comment: "") case .InstallApp(let message): return NSLocalizedString("Unable to install the app: \(message.toString())", comment: "") case .UninstallApp: From f23a7e9c82e4cc547661ac02eecbd19feee7a86c Mon Sep 17 00:00:00 2001 From: CelloSerenity <195480169+CelloSerenity@users.noreply.github.com> Date: Fri, 10 Oct 2025 14:56:54 -0600 Subject: [PATCH 2/6] Enhance error messages for UDID and SideJIT issues Signed-off-by: CelloSerenity <195480169+CelloSerenity@users.noreply.github.com> --- AltStore/Operations/Errors/OperationError.swift | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/AltStore/Operations/Errors/OperationError.swift b/AltStore/Operations/Errors/OperationError.swift index 40f2dcee..c630d8ad 100644 --- a/AltStore/Operations/Errors/OperationError.swift +++ b/AltStore/Operations/Errors/OperationError.swift @@ -201,7 +201,7 @@ struct OperationError: ALTLocalizedError { case .unknownResult: return NSLocalizedString("The operation returned an unknown result.", comment: "") case .timedOut: return NSLocalizedString("The operation timed out.", comment: "") case .notAuthenticated: return NSLocalizedString("You are not signed in.", comment: "") - case .unknownUDID: return NSLocalizedString("SideStore could not determine this device's UDID.", comment: "") + case .unknownUDID: return NSLocalizedString("SideStore could not determine this device's UDID. Please recreate your pairing using idevice_pair.", comment: "") case .invalidApp: return NSLocalizedString("The app is in an invalid format.", comment: "") case .maximumAppIDLimitReached: return NSLocalizedString("Cannot register more than 10 App IDs within a 7 day period.", comment: "") case .noSources: return NSLocalizedString("There are no SideStore sources.", comment: "") @@ -222,10 +222,10 @@ struct OperationError: ALTLocalizedError { return String(format: NSLocalizedString("SideStore was denied permission to launch %@.", comment: ""), appName) case .noWiFi: return NSLocalizedString("You do not appear to be connected to Wi-Fi and/or StosVPN!\nSideStore will never be able to install or refresh applications without Wi-Fi and StosVPN.", comment: "") case .tooNewError: return NSLocalizedString("iOS 17.0-17.3.1 changed how JIT is enabled so SideStore cannot enable JIT without SideJITServer on these versions, sorry for any inconvenience.", comment: "") - case .unableToConnectSideJIT: return NSLocalizedString("Unable to connect to SideJITServer. Please check that you are on the same Wi-Fi of and your Firewall has been set correctly on your server", comment: "") - case .unableToRespondSideJITDevice: return NSLocalizedString("SideJITServer is unable to connect to your iDevice. Please make sure you have paired your iDevice by running 'SideJITServer -y', or try refreshing SideJITServer from Settings", comment: "") + case .unableToConnectSideJIT: return NSLocalizedString("Unable to connect to SideJITServer. Please check that you are on the same Wi-Fi of and your Firewall has been set correctly on your server.", comment: "") + case .unableToRespondSideJITDevice: return NSLocalizedString("SideJITServer is unable to connect to your iDevice. Please make sure you have paired your iDevice by running 'SideJITServer -y', or try refreshing SideJITServer from Settings.", comment: "") case .wrongSideJITIP: return NSLocalizedString("Incorrect SideJITServer IP. Please make sure that you are on the same Wi-Fi as SideJITServer", comment: "") - case .refreshsidejit: return NSLocalizedString("Unable to find app; Please try refreshing SideJITServer from Settings", comment: "") + case .refreshsidejit: return NSLocalizedString("Unable to find app; Please try refreshing SideJITServer from Settings.", comment: "") case .anisetteV1Error: return NSLocalizedString("An error occurred while getting anisette data from a V1 server: %@. Try using another anisette server.", comment: "") case .provisioningError: return NSLocalizedString("An error occurred while provisioning: %@ %@. Please try again. If the issue persists, report it on GitHub Issues!", comment: "") case .anisetteV3Error: return NSLocalizedString("An error occurred while getting anisette data from a V3 server: %@. Please try again. If the issue persists, report it on GitHub Issues!", comment: "") From d98e0dde7216f48b605209d30780e18e3fef8b64 Mon Sep 17 00:00:00 2001 From: CelloSerenity <195480169+CelloSerenity@users.noreply.github.com> Date: Fri, 10 Oct 2025 15:34:12 -0600 Subject: [PATCH 3/6] Update OperationError.swift Signed-off-by: CelloSerenity <195480169+CelloSerenity@users.noreply.github.com> --- AltStore/Operations/Errors/OperationError.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/AltStore/Operations/Errors/OperationError.swift b/AltStore/Operations/Errors/OperationError.swift index c630d8ad..f8bec67d 100644 --- a/AltStore/Operations/Errors/OperationError.swift +++ b/AltStore/Operations/Errors/OperationError.swift @@ -220,7 +220,7 @@ struct OperationError: ALTLocalizedError { case .openAppFailed: let appName = self.appName ?? NSLocalizedString("The app", comment: "") return String(format: NSLocalizedString("SideStore was denied permission to launch %@.", comment: ""), appName) - case .noWiFi: return NSLocalizedString("You do not appear to be connected to Wi-Fi and/or StosVPN!\nSideStore will never be able to install or refresh applications without Wi-Fi and StosVPN.", comment: "") + case .noWiFi: return NSLocalizedString("You do not appear to be connected to Wi-Fi and/or StosVPN!\nSideStore cannot install or refresh applications without Wi-Fi and StosVPN. If both are connected, recreate your pairing with idevice_pair.", comment: "") case .tooNewError: return NSLocalizedString("iOS 17.0-17.3.1 changed how JIT is enabled so SideStore cannot enable JIT without SideJITServer on these versions, sorry for any inconvenience.", comment: "") case .unableToConnectSideJIT: return NSLocalizedString("Unable to connect to SideJITServer. Please check that you are on the same Wi-Fi of and your Firewall has been set correctly on your server.", comment: "") case .unableToRespondSideJITDevice: return NSLocalizedString("SideJITServer is unable to connect to your iDevice. Please make sure you have paired your iDevice by running 'SideJITServer -y', or try refreshing SideJITServer from Settings.", comment: "") @@ -338,7 +338,7 @@ extension MinimuxerError: LocalizedError { case .CreateAfc: return self.createService(name: "AFC") case .RwAfc: - return NSLocalizedString("AFC was unable to manage files on the device. Ensure Wi-Fi is enabled and StosVPN is connected. If they are, recreate your pairing using idevice_pair.", comment: "") + return NSLocalizedString("AFC was unable to manage files on the device. Ensure Wi-Fi and StosVPN are connected. If they both are, recreate your pairing using idevice_pair.", comment: "") case .InstallApp(let message): return NSLocalizedString("Unable to install the app: \(message.toString())", comment: "") case .UninstallApp: From 7a34d7ac679b244ba981a3c18983bd630a41f553 Mon Sep 17 00:00:00 2001 From: CelloSerenity <195480169+CelloSerenity@users.noreply.github.com> Date: Sat, 8 Nov 2025 19:23:59 -0700 Subject: [PATCH 4/6] Fix version numbering --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 70ebb03a..88588505 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ SideStore's goal is to provide an untethered sideloading experience. It's a comm ## Requirements - Xcode 15 -- iOS 15+ +- iOS 14+ - Rustup (`brew install rustup`) Why iOS 15? Targeting such a recent version of iOS allows us to accelerate development, especially since not many developers have older devices to test on. This is corrobated by the fact that SwiftUI support is much better, allowing us to transistion to a more modern UI codebase. From f0cb86aff4497c762e105d878e7413291432699e Mon Sep 17 00:00:00 2001 From: CelloSerenity <195480169+CelloSerenity@users.noreply.github.com> Date: Sat, 8 Nov 2025 19:49:50 -0700 Subject: [PATCH 5/6] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 88588505..190a2c2b 100644 --- a/README.md +++ b/README.md @@ -21,17 +21,17 @@ SideStore's goal is to provide an untethered sideloading experience. It's a comm - iOS 14+ - Rustup (`brew install rustup`) -Why iOS 15? Targeting such a recent version of iOS allows us to accelerate development, especially since not many developers have older devices to test on. This is corrobated by the fact that SwiftUI support is much better, allowing us to transistion to a more modern UI codebase. +Why iOS 14? Targeting such a recent version of iOS allows us to accelerate development, especially since not many developers have older devices to test on. This is corrobated by the fact that SwiftUI support is much better, allowing us to transistion to a more modern UI codebase. ## Project Overview ### SideStore SideStore is a just regular, sandboxed iOS application. The AltStore app target contains the vast majority of SideStore's functionality, including all the logic for downloading and updating apps through SideStore. SideStore makes heavy use of standard iOS frameworks and technologies most iOS developers are familiar with. ### EM Proxy -[SideServer mobile](https://github.com/jkcoxson/em_proxy) powers the defining feature of SideStore: untethered app installation. By leveraging a custom-built App Store app with additional entitlements (StosVPN) to create the VPN tunnel for us, it allows SideStore to take advantage of [Jitterbug](https://github.com/osy/Jitterbug)'s loopback method without requiring a paid developer account. +[EM Proxy](https://github.com/jkcoxson/em_proxy) powers the defining feature of SideStore: untethered app installation. By leveraging a custom-built App Store app with additional entitlements ([StosVPN](https://github.com/SideStore/StosVPN)) to create the VPN tunnel for us, it allows SideStore to take advantage of [Jitterbug](https://github.com/osy/Jitterbug)'s loopback method without requiring a paid developer account. ### Minimuxer -[Minimuxer](https://github.com/jkcoxson/minimuxer) is a lockdown muxer that can run inside iOS’s sandbox. It replicates Apple’s usbmuxd protocol on MacOS to “discover” devices to interface with StosVPN On-Device. +[Minimuxer](https://github.com/jkcoxson/minimuxer) is a lockdown muxer that can run inside iOS’s sandbox. It replicates Apple’s usbmuxd protocol on macOS to “discover” devices to interface with StosVPN on-device. ### Roxas [Roxas](https://github.com/rileytestut/roxas) is Riley Testut's internal framework from AltStore used across many of their iOS projects, developed to simplify a variety of common tasks used in iOS development. From d042267ff9d4ba9f46eb47f0499526669e994473 Mon Sep 17 00:00:00 2001 From: CelloSerenity <195480169+CelloSerenity@users.noreply.github.com> Date: Thu, 20 Nov 2025 16:50:45 -0700 Subject: [PATCH 6/6] Update error messages to reference iloader Signed-off-by: CelloSerenity <195480169+CelloSerenity@users.noreply.github.com> --- AltStore/Operations/Errors/OperationError.swift | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/AltStore/Operations/Errors/OperationError.swift b/AltStore/Operations/Errors/OperationError.swift index f8bec67d..52b4ccf0 100644 --- a/AltStore/Operations/Errors/OperationError.swift +++ b/AltStore/Operations/Errors/OperationError.swift @@ -201,7 +201,7 @@ struct OperationError: ALTLocalizedError { case .unknownResult: return NSLocalizedString("The operation returned an unknown result.", comment: "") case .timedOut: return NSLocalizedString("The operation timed out.", comment: "") case .notAuthenticated: return NSLocalizedString("You are not signed in.", comment: "") - case .unknownUDID: return NSLocalizedString("SideStore could not determine this device's UDID. Please recreate your pairing using idevice_pair.", comment: "") + case .unknownUDID: return NSLocalizedString("SideStore could not determine this device's UDID. Please replace your pairing using iloader.", comment: "") case .invalidApp: return NSLocalizedString("The app is in an invalid format.", comment: "") case .maximumAppIDLimitReached: return NSLocalizedString("Cannot register more than 10 App IDs within a 7 day period.", comment: "") case .noSources: return NSLocalizedString("There are no SideStore sources.", comment: "") @@ -220,7 +220,7 @@ struct OperationError: ALTLocalizedError { case .openAppFailed: let appName = self.appName ?? NSLocalizedString("The app", comment: "") return String(format: NSLocalizedString("SideStore was denied permission to launch %@.", comment: ""), appName) - case .noWiFi: return NSLocalizedString("You do not appear to be connected to Wi-Fi and/or StosVPN!\nSideStore cannot install or refresh applications without Wi-Fi and StosVPN. If both are connected, recreate your pairing with idevice_pair.", comment: "") + case .noWiFi: return NSLocalizedString("You do not appear to be connected to Wi-Fi and/or StosVPN!\nSideStore cannot install or refresh applications without Wi-Fi and StosVPN. If both are connected, replace your pairing with iloader.", comment: "") case .tooNewError: return NSLocalizedString("iOS 17.0-17.3.1 changed how JIT is enabled so SideStore cannot enable JIT without SideJITServer on these versions, sorry for any inconvenience.", comment: "") case .unableToConnectSideJIT: return NSLocalizedString("Unable to connect to SideJITServer. Please check that you are on the same Wi-Fi of and your Firewall has been set correctly on your server.", comment: "") case .unableToRespondSideJITDevice: return NSLocalizedString("SideJITServer is unable to connect to your iDevice. Please make sure you have paired your iDevice by running 'SideJITServer -y', or try refreshing SideJITServer from Settings.", comment: "") @@ -310,7 +310,7 @@ extension MinimuxerError: LocalizedError { case .NoConnection: return NSLocalizedString("Unable to connect to the device, make sure StosVPN is enabled and you're connected to Wi-Fi. This could mean an invalid pairing.", comment: "") case .PairingFile: - return NSLocalizedString("Invalid pairing file. Your pairing file either didn't have a UDID, or it wasn't a valid plist. Please use idevice_pair to recreate it.", comment: "") + return NSLocalizedString("Invalid pairing file. Your pairing file either didn't have a UDID, or it wasn't a valid plist. Please use iloader to replace it.", comment: "") case .CreateDebug: return self.createService(name: "debug") @@ -338,7 +338,7 @@ extension MinimuxerError: LocalizedError { case .CreateAfc: return self.createService(name: "AFC") case .RwAfc: - return NSLocalizedString("AFC was unable to manage files on the device. Ensure Wi-Fi and StosVPN are connected. If they both are, recreate your pairing using idevice_pair.", comment: "") + return NSLocalizedString("AFC was unable to manage files on the device. Ensure Wi-Fi and StosVPN are connected. If they both are, replace your pairing using iloader.", comment: "") case .InstallApp(let message): return NSLocalizedString("Unable to install the app: \(message.toString())", comment: "") case .UninstallApp: