mirror of
https://github.com/SideStore/SideStore.git
synced 2026-02-09 06:43:25 +01:00
Improves 10 App ID limit error handling
This commit is contained in:
@@ -502,8 +502,8 @@ extension AppViewController
|
||||
catch
|
||||
{
|
||||
DispatchQueue.main.async {
|
||||
let toastView = ToastView(text: error.localizedDescription, detailText: nil)
|
||||
toastView.show(in: self.navigationController?.view ?? self.view, duration: 2)
|
||||
let toastView = ToastView(error: error)
|
||||
toastView.show(in: self)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -255,8 +255,8 @@ private extension BrowseViewController
|
||||
{
|
||||
case .failure(OperationError.cancelled): break // Ignore
|
||||
case .failure(let error):
|
||||
let toastView = ToastView(text: error.localizedDescription, detailText: nil)
|
||||
toastView.show(in: self.navigationController?.view ?? self.view, duration: 2)
|
||||
let toastView = ToastView(error: error)
|
||||
toastView.show(in: self)
|
||||
|
||||
case .success: print("Installed app:", app.bundleIdentifier)
|
||||
}
|
||||
|
||||
@@ -10,11 +10,35 @@ import Roxas
|
||||
|
||||
class ToastView: RSTToastView
|
||||
{
|
||||
var preferredDuration: TimeInterval
|
||||
|
||||
override init(text: String, detailText detailedText: String?)
|
||||
{
|
||||
if detailedText == nil
|
||||
{
|
||||
self.preferredDuration = 2.0
|
||||
}
|
||||
else
|
||||
{
|
||||
self.preferredDuration = 8.0
|
||||
}
|
||||
|
||||
super.init(text: text, detailText: detailedText)
|
||||
|
||||
self.layoutMargins = UIEdgeInsets(top: 6, left: 12, bottom: 6, right: 12)
|
||||
self.setNeedsLayout()
|
||||
}
|
||||
|
||||
convenience init(error: Error)
|
||||
{
|
||||
if let error = error as? LocalizedError
|
||||
{
|
||||
self.init(text: error.localizedDescription, detailText: error.recoverySuggestion ?? error.failureReason)
|
||||
}
|
||||
else
|
||||
{
|
||||
self.init(text: error.localizedDescription, detailText: nil)
|
||||
}
|
||||
}
|
||||
|
||||
required init(coder aDecoder: NSCoder) {
|
||||
@@ -27,4 +51,14 @@ class ToastView: RSTToastView
|
||||
|
||||
self.layer.cornerRadius = 16
|
||||
}
|
||||
|
||||
func show(in viewController: UIViewController)
|
||||
{
|
||||
self.show(in: viewController.navigationController?.view ?? viewController.view, duration: self.preferredDuration)
|
||||
}
|
||||
|
||||
override func show(in view: UIView)
|
||||
{
|
||||
self.show(in: view, duration: self.preferredDuration)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -383,9 +383,8 @@ private extension MyAppsViewController
|
||||
switch result
|
||||
{
|
||||
case .failure(let error):
|
||||
let toastView = ToastView(text: error.localizedDescription, detailText: nil)
|
||||
toastView.setNeedsLayout()
|
||||
toastView.show(in: self.navigationController?.view ?? self.view, duration: 2.0)
|
||||
let toastView = ToastView(error: error)
|
||||
toastView.show(in: self)
|
||||
|
||||
case .success(let results):
|
||||
let failures = results.compactMapValues { (result) -> Error? in
|
||||
@@ -399,22 +398,32 @@ private extension MyAppsViewController
|
||||
|
||||
guard !failures.isEmpty else { break }
|
||||
|
||||
let localizedText: String
|
||||
let detailText: String?
|
||||
let toastView: ToastView
|
||||
|
||||
if let failure = failures.first, failures.count == 1
|
||||
if let failure = failures.first, results.count == 1
|
||||
{
|
||||
localizedText = failure.value.localizedDescription
|
||||
detailText = nil
|
||||
toastView = ToastView(error: failure.value)
|
||||
}
|
||||
else
|
||||
{
|
||||
localizedText = String(format: NSLocalizedString("Failed to refresh %@ apps.", comment: ""), NSNumber(value: failures.count))
|
||||
detailText = failures.first?.value.localizedDescription
|
||||
let localizedText: String
|
||||
|
||||
if failures.count == 1
|
||||
{
|
||||
localizedText = NSLocalizedString("Failed to refresh 1 app.", comment: "")
|
||||
}
|
||||
else
|
||||
{
|
||||
localizedText = String(format: NSLocalizedString("Failed to refresh %@ apps.", comment: ""), NSNumber(value: failures.count))
|
||||
}
|
||||
|
||||
let detailText = failures.first?.value.localizedDescription
|
||||
|
||||
toastView = ToastView(text: localizedText, detailText: detailText)
|
||||
toastView.preferredDuration = 2.0
|
||||
}
|
||||
|
||||
let toastView = ToastView(text: localizedText, detailText: detailText)
|
||||
toastView.show(in: self.navigationController?.view ?? self.view, duration: 2.0)
|
||||
toastView.show(in: self)
|
||||
}
|
||||
|
||||
self.refreshGroup = nil
|
||||
@@ -574,8 +583,8 @@ private extension MyAppsViewController
|
||||
self.collectionView.reloadItems(at: [indexPath])
|
||||
|
||||
case .failure(let error):
|
||||
let toastView = ToastView(text: error.localizedDescription, detailText: nil)
|
||||
toastView.show(in: self.navigationController?.view ?? self.view, duration: 2)
|
||||
let toastView = ToastView(error: error)
|
||||
toastView.show(in: self)
|
||||
|
||||
self.collectionView.reloadItems(at: [indexPath])
|
||||
|
||||
@@ -637,8 +646,8 @@ private extension MyAppsViewController
|
||||
DispatchQueue.main.async {
|
||||
if let error = result.error
|
||||
{
|
||||
let toastView = ToastView(text: error.localizedDescription, detailText: nil)
|
||||
toastView.show(in: self.navigationController?.view ?? self.view, duration: 2.0)
|
||||
let toastView = ToastView(error: error)
|
||||
toastView.show(in: self)
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -666,8 +675,8 @@ private extension MyAppsViewController
|
||||
DispatchQueue.main.async {
|
||||
self.navigationItem.leftBarButtonItem?.isIndicatingActivity = false
|
||||
|
||||
let toastView = ToastView(text: error.localizedDescription, detailText: nil)
|
||||
toastView.show(in: self.navigationController?.view ?? self.view, duration: 2.0)
|
||||
let toastView = ToastView(error: error)
|
||||
toastView.show(in: self)
|
||||
}
|
||||
|
||||
completion(.failure(error))
|
||||
|
||||
@@ -24,6 +24,7 @@ enum OperationError: LocalizedError
|
||||
case invalidParameters
|
||||
|
||||
case iOSVersionNotSupported(ALTApplication)
|
||||
case maximumAppIDLimitReached(Date)
|
||||
|
||||
case noSources
|
||||
|
||||
@@ -49,6 +50,37 @@ enum OperationError: LocalizedError
|
||||
|
||||
let localizedDescription = String(format: NSLocalizedString("%@ requires %@.", comment: ""), name, version)
|
||||
return localizedDescription
|
||||
|
||||
case .maximumAppIDLimitReached: return NSLocalizedString("Cannot register more than 10 App IDs.", comment: "")
|
||||
}
|
||||
}
|
||||
|
||||
var recoverySuggestion: String? {
|
||||
switch self
|
||||
{
|
||||
case .maximumAppIDLimitReached(let date):
|
||||
let remainingTime: String
|
||||
|
||||
let numberOfDays = date.numberOfCalendarDays(since: Date())
|
||||
switch numberOfDays {
|
||||
case 0:
|
||||
let components = Calendar.current.dateComponents([.hour], from: Date(), to: date)
|
||||
let numberOfHours = components.hour!
|
||||
|
||||
switch numberOfHours
|
||||
{
|
||||
case 1: remainingTime = NSLocalizedString("1 hour", comment: "")
|
||||
default: remainingTime = String(format: NSLocalizedString("%@ hours", comment: ""), NSNumber(value: numberOfHours))
|
||||
}
|
||||
|
||||
case 1: remainingTime = NSLocalizedString("1 day", comment: "")
|
||||
default: remainingTime = String(format: NSLocalizedString("%@ days", comment: ""), NSNumber(value: numberOfDays))
|
||||
}
|
||||
|
||||
let message = String(format: NSLocalizedString("Delete sideloaded apps to free up App ID slots. You can register another App ID in %@.", comment: ""), remainingTime)
|
||||
return message
|
||||
|
||||
default: return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -231,7 +231,31 @@ private extension ResignAppOperation
|
||||
else
|
||||
{
|
||||
ALTAppleAPI.shared.addAppID(withName: appName, bundleIdentifier: bundleIdentifier, team: team, session: session) { (appID, error) in
|
||||
completionHandler(Result(appID, error))
|
||||
do
|
||||
{
|
||||
do
|
||||
{
|
||||
let appID = try Result(appID, error).get()
|
||||
completionHandler(.success(appID))
|
||||
}
|
||||
catch ALTAppleAPIError.maximumAppIDLimitReached
|
||||
{
|
||||
let sortedExpirationDates = appIDs.compactMap { $0.expirationDate }.sorted(by: { $0 < $1 })
|
||||
|
||||
if let expirationDate = sortedExpirationDates.first
|
||||
{
|
||||
throw OperationError.maximumAppIDLimitReached(expirationDate)
|
||||
}
|
||||
else
|
||||
{
|
||||
throw ALTAppleAPIError(.maximumAppIDLimitReached)
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
completionHandler(.failure(error))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
2
Dependencies/AltSign
vendored
2
Dependencies/AltSign
vendored
Submodule Dependencies/AltSign updated: 4b43efed0d...8afbc8a845
Reference in New Issue
Block a user