mirror of
https://github.com/SideStore/SideStore.git
synced 2026-02-19 19:53:25 +01:00
Downloads latest _available_ version when updating from AppViewController
Asks user to fall back to latest supported verson if version is not compatible with device’s iOS version.
This commit is contained in:
@@ -360,13 +360,21 @@ private extension AppViewController
|
|||||||
{
|
{
|
||||||
func update()
|
func update()
|
||||||
{
|
{
|
||||||
|
var buttonAction: AppBannerView.AppAction?
|
||||||
|
|
||||||
|
if let installedApp = self.app.installedApp, let latestVersion = self.app.latestAvailableVersion, !installedApp.matches(latestVersion)
|
||||||
|
{
|
||||||
|
// Explicitly set button action to .update if there is an update available, even if it's not supported.
|
||||||
|
buttonAction = .update
|
||||||
|
}
|
||||||
|
|
||||||
for button in [self.bannerView.button!, self.navigationBarDownloadButton!]
|
for button in [self.bannerView.button!, self.navigationBarDownloadButton!]
|
||||||
{
|
{
|
||||||
button.tintColor = self.app.tintColor
|
button.tintColor = self.app.tintColor
|
||||||
button.isIndicatingActivity = false
|
button.isIndicatingActivity = false
|
||||||
}
|
}
|
||||||
|
|
||||||
self.bannerView.configure(for: self.app)
|
self.bannerView.configure(for: self.app, action: buttonAction)
|
||||||
|
|
||||||
let title = self.bannerView.button.title(for: .normal)
|
let title = self.bannerView.button.title(for: .normal)
|
||||||
self.navigationBarDownloadButton.setTitle(title, for: .normal)
|
self.navigationBarDownloadButton.setTitle(title, for: .normal)
|
||||||
@@ -498,9 +506,9 @@ extension AppViewController
|
|||||||
{
|
{
|
||||||
if let installedApp = self.app.installedApp
|
if let installedApp = self.app.installedApp
|
||||||
{
|
{
|
||||||
if let latestVersion = self.app.latestSupportedVersion, !installedApp.matches(latestVersion)
|
if let latestVersion = self.app.latestAvailableVersion, !installedApp.matches(latestVersion)
|
||||||
{
|
{
|
||||||
self.updateApp(installedApp)
|
self.updateApp(installedApp, to: latestVersion)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -551,7 +559,7 @@ extension AppViewController
|
|||||||
UIApplication.shared.open(installedApp.openAppURL)
|
UIApplication.shared.open(installedApp.openAppURL)
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateApp(_ installedApp: InstalledApp)
|
func updateApp(_ installedApp: InstalledApp, to version: AppVersion)
|
||||||
{
|
{
|
||||||
let previousProgress = AppManager.shared.installationProgress(for: installedApp)
|
let previousProgress = AppManager.shared.installationProgress(for: installedApp)
|
||||||
guard previousProgress == nil else {
|
guard previousProgress == nil else {
|
||||||
@@ -560,7 +568,7 @@ extension AppViewController
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
_ = AppManager.shared.update(installedApp, presentingViewController: self) { (result) in
|
AppManager.shared.update(installedApp, to: version, presentingViewController: self) { (result) in
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
switch result
|
switch result
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -557,9 +557,9 @@ extension AppManager
|
|||||||
}
|
}
|
||||||
|
|
||||||
@discardableResult
|
@discardableResult
|
||||||
func update(_ installedApp: InstalledApp, presentingViewController: UIViewController?, context: AuthenticatedOperationContext = AuthenticatedOperationContext(), completionHandler: @escaping (Result<InstalledApp, Error>) -> Void) -> Progress
|
func update(_ installedApp: InstalledApp, to version: AppVersion? = nil, presentingViewController: UIViewController?, context: AuthenticatedOperationContext = AuthenticatedOperationContext(), completionHandler: @escaping (Result<InstalledApp, Error>) -> Void) -> Progress
|
||||||
{
|
{
|
||||||
guard let appVersion = installedApp.storeApp?.latestSupportedVersion else {
|
guard let appVersion = version ?? installedApp.storeApp?.latestSupportedVersion else {
|
||||||
completionHandler(.failure(OperationError.appNotFound(name: installedApp.name)))
|
completionHandler(.failure(OperationError.appNotFound(name: installedApp.name)))
|
||||||
return Progress.discreteProgress(totalUnitCount: 1)
|
return Progress.discreteProgress(totalUnitCount: 1)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,9 @@ import Roxas
|
|||||||
@objc(DownloadAppOperation)
|
@objc(DownloadAppOperation)
|
||||||
class DownloadAppOperation: ResultOperation<ALTApplication>
|
class DownloadAppOperation: ResultOperation<ALTApplication>
|
||||||
{
|
{
|
||||||
let app: AppProtocol
|
@Managed
|
||||||
|
private(set) var app: AppProtocol
|
||||||
|
|
||||||
let context: InstallAppOperationContext
|
let context: InstallAppOperationContext
|
||||||
|
|
||||||
private let appName: String
|
private let appName: String
|
||||||
@@ -59,22 +61,36 @@ class DownloadAppOperation: ResultOperation<ALTApplication>
|
|||||||
// Set _after_ checking self.context.error to prevent overwriting localized failure for previous errors.
|
// Set _after_ checking self.context.error to prevent overwriting localized failure for previous errors.
|
||||||
self.localizedFailure = String(format: NSLocalizedString("%@ could not be downloaded.", comment: ""), self.appName)
|
self.localizedFailure = String(format: NSLocalizedString("%@ could not be downloaded.", comment: ""), self.appName)
|
||||||
|
|
||||||
guard let storeApp = self.app as? StoreApp else {
|
self.$app.perform { app in
|
||||||
// Only StoreApp allows falling back to previous versions.
|
|
||||||
// AppVersion can only install itself, and ALTApplication doesn't have previous versions.
|
|
||||||
return self.download(self.app)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify storeApp
|
|
||||||
storeApp.managedObjectContext?.perform {
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
let latestVersion = try self.verify(storeApp)
|
var appVersion: AppVersion?
|
||||||
self.download(latestVersion)
|
|
||||||
|
if let version = app as? AppVersion
|
||||||
|
{
|
||||||
|
appVersion = version
|
||||||
|
}
|
||||||
|
else if let storeApp = app as? StoreApp
|
||||||
|
{
|
||||||
|
guard let latestVersion = storeApp.latestAvailableVersion else {
|
||||||
|
let failureReason = String(format: NSLocalizedString("The latest version of %@ could not be determined.", comment: ""), self.appName)
|
||||||
|
throw OperationError.unknown(failureReason: failureReason)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attempt to download latest _available_ version, and fall back to older versions if necessary.
|
||||||
|
appVersion = latestVersion
|
||||||
|
}
|
||||||
|
|
||||||
|
if let appVersion
|
||||||
|
{
|
||||||
|
try self.verify(appVersion)
|
||||||
|
}
|
||||||
|
|
||||||
|
self.download(appVersion ?? app)
|
||||||
}
|
}
|
||||||
catch let error as VerificationError where error.code == .iOSVersionNotSupported
|
catch let error as VerificationError where error.code == .iOSVersionNotSupported
|
||||||
{
|
{
|
||||||
guard let presentingViewController = self.context.presentingViewController, let latestSupportedVersion = storeApp.latestSupportedVersion
|
guard let presentingViewController = self.context.presentingViewController, let storeApp = app.storeApp, let latestSupportedVersion = storeApp.latestSupportedVersion
|
||||||
else { return self.finish(.failure(error)) }
|
else { return self.finish(.failure(error)) }
|
||||||
|
|
||||||
if let installedApp = storeApp.installedApp
|
if let installedApp = storeApp.installedApp
|
||||||
@@ -121,23 +137,16 @@ class DownloadAppOperation: ResultOperation<ALTApplication>
|
|||||||
|
|
||||||
private extension DownloadAppOperation
|
private extension DownloadAppOperation
|
||||||
{
|
{
|
||||||
func verify(_ storeApp: StoreApp) throws -> AppVersion
|
func verify(_ version: AppVersion) throws
|
||||||
{
|
{
|
||||||
guard let version = storeApp.latestAvailableVersion else {
|
|
||||||
let failureReason = String(format: NSLocalizedString("The latest version of %@ could not be determined.", comment: ""), self.appName)
|
|
||||||
throw OperationError.unknown(failureReason: failureReason)
|
|
||||||
}
|
|
||||||
|
|
||||||
if let minOSVersion = version.minOSVersion, !ProcessInfo.processInfo.isOperatingSystemAtLeast(minOSVersion)
|
if let minOSVersion = version.minOSVersion, !ProcessInfo.processInfo.isOperatingSystemAtLeast(minOSVersion)
|
||||||
{
|
{
|
||||||
throw VerificationError.iOSVersionNotSupported(app: storeApp, requiredOSVersion: minOSVersion)
|
throw VerificationError.iOSVersionNotSupported(app: version, requiredOSVersion: minOSVersion)
|
||||||
}
|
}
|
||||||
else if let maxOSVersion = version.maxOSVersion, ProcessInfo.processInfo.operatingSystemVersion > maxOSVersion
|
else if let maxOSVersion = version.maxOSVersion, ProcessInfo.processInfo.operatingSystemVersion > maxOSVersion
|
||||||
{
|
{
|
||||||
throw VerificationError.iOSVersionNotSupported(app: storeApp, requiredOSVersion: maxOSVersion)
|
throw VerificationError.iOSVersionNotSupported(app: version, requiredOSVersion: maxOSVersion)
|
||||||
}
|
}
|
||||||
|
|
||||||
return version
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func download(@Managed _ app: AppProtocol)
|
func download(@Managed _ app: AppProtocol)
|
||||||
|
|||||||
Reference in New Issue
Block a user