Uses same error code with different debug descriptions. These errors should never be thrown in production so no need for unique codes, but if they do get thrown then they include enough technical information to debug.
Replaces OperationError.appNotFound
In addition to removing the app extensions themselves, we also need to remove references to them from SC_Info/Manifest.plist in the app bundle (if the file exists). Otherwise, subsequent installations (resigning, (de)-activating, etc.) will fail due to “missing” app extensions.
As of iOS 16, iOS apps can no longer read the device name. This means devices registered with AltStore (not AltServer) have generic names, so we should prefer using the name of provided ALTDevice rather than the name of device returned from server to ensure it’s correct.
AltStore assumes all apps have unique bundle IDs per source. Weird bugs can occur when this is not the case (such as merging multiple store listings into one), so we now verify upfront whether source contains duplicate bundle IDs before saving.
Unlike MyAppsViewController, AppViewController will attempt to update to the latest available version, rather than the latest supported version. If the latest version is not supported, it will fall back to asking user to install last supported version.
When unsupported updates are available, the “No Updates Available” text becomes “Unsupported Updates Available”, and a button is revealed that will list all unsupported updates in an alert when tapped.
This allows us to use @Managed with properties that may or may not be NSManagedObjects at runtime (e.g. protocols). If they are, Managed will keep strong reference to context like before.
We now store the latest supported version as a relationship on StoreApp, rather than the latest available version. This allows us to reference the latest supported version in predicates and sort descriptors.
However, we kept the underlying Core Data property name the same to avoid extra migration.
Previously, AltStore would quit all other processes when first accessing the database no matter what. However, this unintentionally caused the widget extension to quit the main app after refreshing apps.
Now, we only quit other AltStore processes if a database migration is required. This still prevents multiple AltStores with different database schemas from accessing database concurrently, but also allows extensions to access database without quitting main app.