2019-06-10 15:03:47 -07:00
//
// O p e r a t i o n E r r o r . s w i f t
// A l t S t o r e
//
// C r e a t e d b y R i l e y T e s t u t o n 6 / 7 / 1 9 .
// C o p y r i g h t © 2 0 1 9 R i l e y T e s t u t . A l l r i g h t s r e s e r v e d .
//
import Foundation
2019-07-25 14:04:26 -07:00
import AltSign
2023-01-24 13:56:41 -06:00
import AltStoreCore
2019-06-10 15:03:47 -07:00
2023-01-24 13:56:41 -06:00
extension OperationError
2019-06-10 15:03:47 -07:00
{
2023-01-24 13:56:41 -06:00
enum Code : Int , ALTErrorCode , CaseIterable
{
typealias Error = OperationError
/* G e n e r a l */
case unknown = 1000
case unknownResult
case cancelled
case timedOut
case notAuthenticated
case appNotFound
case unknownUDID
case invalidApp
case invalidParameters
case maximumAppIDLimitReached
case noSources
case openAppFailed
case missingAppGroup
/* C o n n e c t i o n */
case serverNotFound = 1200
case connectionFailed
case connectionDropped
}
static let unknownResult : OperationError = . init ( code : . unknownResult )
static let cancelled : OperationError = . init ( code : . cancelled )
static let timedOut : OperationError = . init ( code : . timedOut )
static let notAuthenticated : OperationError = . init ( code : . notAuthenticated )
static let unknownUDID : OperationError = . init ( code : . unknownUDID )
static let invalidApp : OperationError = . init ( code : . invalidApp )
static let invalidParameters : OperationError = . init ( code : . invalidParameters )
static let noSources : OperationError = . init ( code : . noSources )
static let missingAppGroup : OperationError = . init ( code : . missingAppGroup )
static let serverNotFound : OperationError = . init ( code : . serverNotFound )
static let connectionFailed : OperationError = . init ( code : . connectionFailed )
static let connectionDropped : OperationError = . init ( code : . connectionDropped )
2022-09-09 17:44:15 -05:00
2023-01-24 13:56:41 -06:00
static func unknown ( failureReason : String ? = nil , file : String = # fileID , line : UInt = #line ) -> OperationError {
OperationError ( code : . unknown , failureReason : failureReason , sourceFile : file , sourceLine : line )
}
2019-06-10 15:03:47 -07:00
2023-01-24 13:56:41 -06:00
static func appNotFound ( name : String ? ) -> OperationError { OperationError ( code : . appNotFound , appName : name ) }
static func openAppFailed ( name : String ) -> OperationError { OperationError ( code : . openAppFailed , appName : name ) }
2019-06-10 15:03:47 -07:00
2023-01-24 13:56:41 -06:00
static func maximumAppIDLimitReached ( appName : String , requiredAppIDs : Int , availableAppIDs : Int , expirationDate : Date ) -> OperationError {
OperationError ( code : . maximumAppIDLimitReached , appName : appName , requiredAppIDs : requiredAppIDs , availableAppIDs : availableAppIDs , expirationDate : expirationDate )
}
}
struct OperationError : ALTLocalizedError
{
let code : Code
2019-06-10 15:03:47 -07:00
2023-01-24 13:56:41 -06:00
var errorTitle : String ?
var errorFailure : String ?
2019-06-21 11:20:03 -07:00
2023-01-24 13:56:41 -06:00
var appName : String ?
var requiredAppIDs : Int ?
var availableAppIDs : Int ?
var expirationDate : Date ?
2019-07-25 14:04:26 -07:00
2023-01-24 13:56:41 -06:00
var sourceFile : String ?
var sourceLine : UInt ?
2019-07-30 17:00:04 -07:00
2023-01-24 13:56:41 -06:00
private init ( code : Code , failureReason : String ? = nil , appName : String ? = nil , requiredAppIDs : Int ? = nil , availableAppIDs : Int ? = nil , expirationDate : Date ? = nil ,
sourceFile : String ? = nil , sourceLine : UInt ? = nil )
{
self . code = code
self . _failureReason = failureReason
self . appName = appName
self . requiredAppIDs = requiredAppIDs
self . availableAppIDs = availableAppIDs
self . expirationDate = expirationDate
self . sourceFile = sourceFile
self . sourceLine = sourceLine
}
2020-05-15 15:11:17 -07:00
2023-01-24 13:56:41 -06:00
var errorFailureReason : String {
switch self . code
{
case . unknown :
var failureReason = self . _failureReason ? ? NSLocalizedString ( " An unknown error occured. " , comment : " " )
guard let sourceFile , let sourceLine else { return failureReason }
failureReason += " ( \( sourceFile ) line \( sourceLine ) ) "
return failureReason
2019-06-10 15:03:47 -07:00
case . unknownResult : return NSLocalizedString ( " The operation returned an unknown result. " , comment : " " )
case . cancelled : return NSLocalizedString ( " The operation was cancelled. " , comment : " " )
2020-05-15 15:11:17 -07:00
case . timedOut : return NSLocalizedString ( " The operation timed out. " , comment : " " )
2019-06-10 15:03:47 -07:00
case . notAuthenticated : return NSLocalizedString ( " You are not signed in. " , comment : " " )
2023-01-24 13:56:41 -06:00
case . unknownUDID : return NSLocalizedString ( " AltStore could not determine this device's UDID. " , comment : " " )
case . invalidApp : return NSLocalizedString ( " The app is in an invalid format. " , comment : " " )
2019-06-21 11:20:03 -07:00
case . invalidParameters : return NSLocalizedString ( " Invalid parameters. " , comment : " " )
2023-01-24 13:56:41 -06:00
case . maximumAppIDLimitReached : return NSLocalizedString ( " You cannot register more than 10 App IDs within a 7 day period. " , comment : " " )
2019-07-30 17:00:04 -07:00
case . noSources : return NSLocalizedString ( " There are no AltStore sources. " , comment : " " )
2023-01-24 13:56:41 -06:00
case . missingAppGroup : return NSLocalizedString ( " AltStore's shared app group could not be accessed. " , comment : " " )
case . appNotFound :
let appName = self . appName ? ? NSLocalizedString ( " The app " , comment : " " )
return String ( format : NSLocalizedString ( " %@ could not be found. " , comment : " " ) , appName )
case . openAppFailed :
let appName = self . appName ? ? NSLocalizedString ( " the app " , comment : " " )
return String ( format : NSLocalizedString ( " AltStore was denied permission to launch %@. " , comment : " " ) , appName )
case . serverNotFound : return NSLocalizedString ( " AltServer could not be found. " , comment : " " )
case . connectionFailed : return NSLocalizedString ( " A connection to AltServer could not be established. " , comment : " " )
case . connectionDropped : return NSLocalizedString ( " The connection to AltServer was dropped. " , comment : " " )
2020-01-24 14:14:08 -08:00
}
}
2023-01-24 13:56:41 -06:00
private var _failureReason : String ?
2020-01-24 14:14:08 -08:00
var recoverySuggestion : String ? {
2023-01-24 13:56:41 -06:00
switch self . code
2020-01-24 14:14:08 -08:00
{
2023-01-24 13:56:41 -06:00
case . serverNotFound : return NSLocalizedString ( " Make sure you're on the same WiFi network as a computer running AltServer, or try connecting this device to your computer via USB. " , comment : " " )
case . maximumAppIDLimitReached :
2020-02-10 16:30:54 -08:00
let baseMessage = NSLocalizedString ( " Delete sideloaded apps to free up App ID slots. " , comment : " " )
2023-01-24 13:56:41 -06:00
guard let appName = self . appName , let requiredAppIDs = self . requiredAppIDs , let availableAppIDs = self . availableAppIDs , let date = self . expirationDate else { return baseMessage }
var message : String = " "
2020-01-24 14:14:08 -08:00
2020-02-10 16:30:54 -08:00
if requiredAppIDs > 1
{
let availableText : String
2020-01-24 14:14:08 -08:00
2020-02-10 16:30:54 -08:00
switch availableAppIDs
2020-01-24 14:14:08 -08:00
{
2020-02-10 16:30:54 -08:00
case 0 : availableText = NSLocalizedString ( " none are available " , comment : " " )
case 1 : availableText = NSLocalizedString ( " only 1 is available " , comment : " " )
default : availableText = String ( format : NSLocalizedString ( " only %@ are available " , comment : " " ) , NSNumber ( value : availableAppIDs ) )
2020-01-24 14:14:08 -08:00
}
2023-01-24 13:56:41 -06:00
let prefixMessage = String ( format : NSLocalizedString ( " %@ requires %@ App IDs, but %@. " , comment : " " ) , appName , NSNumber ( value : requiredAppIDs ) , availableText )
message = prefixMessage + " " + baseMessage + " \n \n "
2020-02-10 16:30:54 -08:00
}
else
{
2023-01-24 13:56:41 -06:00
message = baseMessage + " "
2020-01-24 14:14:08 -08:00
}
2023-01-24 13:56:41 -06:00
let dateComponents = Calendar . current . dateComponents ( [ . day , . hour , . minute ] , from : Date ( ) , to : date )
let dateComponentsFormatter = DateComponentsFormatter ( )
dateComponentsFormatter . maximumUnitCount = 1
dateComponentsFormatter . unitsStyle = . full
let remainingTime = dateComponentsFormatter . string ( from : dateComponents ) !
let remainingTimeMessage = String ( format : NSLocalizedString ( " You can register another App ID in %@. " , comment : " " ) , remainingTime )
message += remainingTimeMessage
2020-01-24 14:14:08 -08:00
return message
default : return nil
2019-06-10 15:03:47 -07:00
}
}
}