From b9dd6432a16e5b893a6ba45de350fec6185f6c7a Mon Sep 17 00:00:00 2001 From: Riley Testut Date: Mon, 15 May 2023 15:38:54 -0500 Subject: [PATCH] Moves SourceError to its own source file --- AltStore.xcodeproj/project.pbxproj | 16 ++- .../{ => Errors}/OperationError.swift | 0 AltStore/Operations/Errors/SourceError.swift | 122 ++++++++++++++++++ .../{ => Errors}/VerificationError.swift | 0 .../Operations/FetchSourceOperation.swift | 113 ---------------- 5 files changed, 136 insertions(+), 115 deletions(-) rename AltStore/Operations/{ => Errors}/OperationError.swift (100%) create mode 100644 AltStore/Operations/Errors/SourceError.swift rename AltStore/Operations/{ => Errors}/VerificationError.swift (100%) diff --git a/AltStore.xcodeproj/project.pbxproj b/AltStore.xcodeproj/project.pbxproj index 0096a398..df4cc2ba 100644 --- a/AltStore.xcodeproj/project.pbxproj +++ b/AltStore.xcodeproj/project.pbxproj @@ -341,6 +341,7 @@ BFF435D8255CBDAB00DD724F /* ALTApplication+AltStoreApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF435D7255CBDAB00DD724F /* ALTApplication+AltStoreApp.swift */; }; BFF615A82510042B00484D3B /* AltStoreCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BF66EE7E2501AE50007EE018 /* AltStoreCore.framework */; }; BFF7C9342578492100E55F36 /* ALTAnisetteData.m in Sources */ = {isa = PBXBuildFile; fileRef = BFB49AA823834CF900D542D9 /* ALTAnisetteData.m */; }; + D513F6162A12CE4E0061EAA1 /* SourceError.swift in Sources */ = {isa = PBXBuildFile; fileRef = D571ADCD2A02FA7400B24B63 /* SourceError.swift */; }; D5189C012A01BC6800F44625 /* UserInfoValue.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5189C002A01BC6800F44625 /* UserInfoValue.swift */; }; D5189C022A01BC6800F44625 /* UserInfoValue.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5189C002A01BC6800F44625 /* UserInfoValue.swift */; }; D519AD46292D665B004B12F9 /* Managed.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFB39B5B252BC10E00D1BE50 /* Managed.swift */; }; @@ -915,6 +916,7 @@ D54DED1328CBC44B008B27A0 /* ErrorLogTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ErrorLogTableViewCell.swift; sourceTree = ""; }; D55E163528776CB000A627A1 /* ComplicationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComplicationView.swift; sourceTree = ""; }; D5708416292448DA00D42D34 /* OperatingSystemVersion+Comparable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "OperatingSystemVersion+Comparable.swift"; sourceTree = ""; }; + D571ADCD2A02FA7400B24B63 /* SourceError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SourceError.swift; sourceTree = ""; }; D571ADCF2A02FC7200B24B63 /* ALTAppPermission.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ALTAppPermission.swift; sourceTree = ""; }; D5728CA62A0D79D30014E73C /* OptionalProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OptionalProtocol.swift; sourceTree = ""; }; D57968CA29CB99EF00539069 /* VibrantButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VibrantButton.swift; sourceTree = ""; }; @@ -1829,8 +1831,7 @@ BFDB6A0922AAEDA1007EA6D6 /* Operations */ = { isa = PBXGroup; children = ( - BFDB6A0C22AAFC19007EA6D6 /* OperationError.swift */, - D5CF56812A0D83F9006D93E2 /* VerificationError.swift */, + D513F6152A12CE210061EAA1 /* Errors */, BFDB6A0A22AAEDB7007EA6D6 /* Operation.swift */, BF770E5722BC3D0F002A40FE /* RefreshGroup.swift */, BF770E5322BC044E002A40FE /* OperationContexts.swift */, @@ -1925,6 +1926,16 @@ path = XPC; sourceTree = ""; }; + D513F6152A12CE210061EAA1 /* Errors */ = { + isa = PBXGroup; + children = ( + BFDB6A0C22AAFC19007EA6D6 /* OperationError.swift */, + D5CF56812A0D83F9006D93E2 /* VerificationError.swift */, + D571ADCD2A02FA7400B24B63 /* SourceError.swift */, + ); + path = Errors; + sourceTree = ""; + }; D586D39928EF58B0000E101F /* AltTests */ = { isa = PBXGroup; children = ( @@ -2704,6 +2715,7 @@ D57F2C9426E01BC700B9FA39 /* UIDevice+Vibration.swift in Sources */, BFD2478F2284C8F900981D42 /* Button.swift in Sources */, D540E93828EE1BDE000F1B0F /* ErrorDetailsViewController.swift in Sources */, + D513F6162A12CE4E0061EAA1 /* SourceError.swift in Sources */, BF56D2AC23DF8E170006506D /* FetchAppIDsOperation.swift in Sources */, BFC1F38D22AEE3A4003AC21A /* DownloadAppOperation.swift in Sources */, BFE6073A231ADF82002B0E8E /* SettingsViewController.swift in Sources */, diff --git a/AltStore/Operations/OperationError.swift b/AltStore/Operations/Errors/OperationError.swift similarity index 100% rename from AltStore/Operations/OperationError.swift rename to AltStore/Operations/Errors/OperationError.swift diff --git a/AltStore/Operations/Errors/SourceError.swift b/AltStore/Operations/Errors/SourceError.swift new file mode 100644 index 00000000..33c3600d --- /dev/null +++ b/AltStore/Operations/Errors/SourceError.swift @@ -0,0 +1,122 @@ +// +// SourceError.swift +// AltStoreCore +// +// Created by Riley Testut on 5/3/23. +// Copyright © 2023 Riley Testut. All rights reserved. +// + +import AltStoreCore + +extension SourceError +{ + enum Code: Int, ALTErrorCode + { + typealias Error = SourceError + + case unsupported + case duplicateBundleID + case duplicateVersion + + case changedID + case duplicate + + case missingPermissionUsageDescription + } + + static func unsupported(_ source: Source) -> SourceError { SourceError(code: .unsupported, source: source) } + static func duplicateBundleID(_ bundleID: String, source: Source) -> SourceError { SourceError(code: .duplicateBundleID, source: source, bundleID: bundleID) } + static func duplicateVersion(_ version: String, for app: StoreApp, source: Source) -> SourceError { SourceError(code: .duplicateVersion, source: source, app: app, version: version) } + + static func changedID(_ identifier: String, previousID: String, source: Source) -> SourceError { SourceError(code: .changedID, source: source, sourceID: identifier, previousSourceID: previousID) } + static func duplicate(_ source: Source, previousSourceName: String?) -> SourceError { SourceError(code: .duplicate, source: source, previousSourceName: previousSourceName) } + + static func missingPermissionUsageDescription(for permission: any ALTAppPermission, app: StoreApp, source: Source) -> SourceError { + SourceError(code: .missingPermissionUsageDescription, source: source, app: app, permission: permission) + } +} + +struct SourceError: ALTLocalizedError +{ + let code: Code + var errorTitle: String? + var errorFailure: String? + + @Managed var source: Source + @Managed var app: StoreApp? + var bundleID: String? + var version: String? + + @UserInfoValue var previousSourceName: String? + + // Store in userInfo so they can be viewed from Error Log. + @UserInfoValue var sourceID: String? + @UserInfoValue var previousSourceID: String? + + @UserInfoValue + var permission: (any ALTAppPermission)? + + var errorFailureReason: String { + switch self.code + { + case .unsupported: return String(format: NSLocalizedString("The source “%@” is not supported by this version of AltStore.", comment: ""), self.$source.name) + case .duplicateBundleID: + let bundleIDFragment = self.bundleID.map { String(format: NSLocalizedString("the bundle identifier %@", comment: ""), $0) } ?? NSLocalizedString("the same bundle identifier", comment: "") + let failureReason = String(format: NSLocalizedString("The source “%@” contains multiple apps with %@.", comment: ""), self.$source.name, bundleIDFragment) + return failureReason + + case .duplicateVersion: + var versionFragment = NSLocalizedString("duplicate versions", comment: "") + if let version + { + versionFragment += " (\(version))" + } + + let appFragment: String + if let name = self.$app.name, let bundleID = self.$app.bundleIdentifier + { + appFragment = name + " (\(bundleID))" + } + else + { + appFragment = NSLocalizedString("one or more apps", comment: "") + } + + let failureReason = String(format: NSLocalizedString("The source “%@” contains %@ for %@.", comment: ""), self.$source.name, versionFragment, appFragment) + return failureReason + + case .changedID: + let failureReason = String(format: NSLocalizedString("The identifier of the source “%@” has changed.", comment: ""), self.$source.name) + return failureReason + + case .duplicate: + let baseMessage = String(format: NSLocalizedString("A source with the identifier '%@' already exists", comment: ""), self.$source.identifier) + guard let previousSourceName else { return baseMessage + "." } + + let failureReason = baseMessage + " (“\(previousSourceName)”)." + return failureReason + + case .missingPermissionUsageDescription: + let appName = self.$app.name ?? String(format: NSLocalizedString("an app in source “%@”", comment: ""), self.$source.name) + guard let permission else { + return String(format: NSLocalizedString("A permission for %@ is missing a usage description.", comment: ""), appName) + } + + let permissionType = permission.type.localizedName ?? NSLocalizedString("Permission", comment: "") + let failureReason = String(format: NSLocalizedString("The %@ '%@' for %@ is missing a usage description.", comment: ""), permissionType.lowercased(), permission.rawValue, appName) + return failureReason + } + } + + var recoverySuggestion: String? { + switch self.code + { + case .changedID: return NSLocalizedString("A source cannot change its identifier once added. This source can no longer be updated.", comment: "") + case .duplicate: + let failureReason = NSLocalizedString("Please remove the existing source in order to add this one.", comment: "") + return failureReason + + default: return nil + } + } +} diff --git a/AltStore/Operations/VerificationError.swift b/AltStore/Operations/Errors/VerificationError.swift similarity index 100% rename from AltStore/Operations/VerificationError.swift rename to AltStore/Operations/Errors/VerificationError.swift diff --git a/AltStore/Operations/FetchSourceOperation.swift b/AltStore/Operations/FetchSourceOperation.swift index a8cce5bc..6d5f10b1 100644 --- a/AltStore/Operations/FetchSourceOperation.swift +++ b/AltStore/Operations/FetchSourceOperation.swift @@ -12,119 +12,6 @@ import CoreData import AltStoreCore import Roxas -extension SourceError -{ - enum Code: Int, ALTErrorCode - { - typealias Error = SourceError - - case unsupported - case duplicateBundleID - case duplicateVersion - - case changedID - case duplicate - - case missingPermissionUsageDescription - } - - static func unsupported(_ source: Source) -> SourceError { SourceError(code: .unsupported, source: source) } - static func duplicateBundleID(_ bundleID: String, source: Source) -> SourceError { SourceError(code: .duplicateBundleID, source: source, bundleID: bundleID) } - static func duplicateVersion(_ version: String, for app: StoreApp, source: Source) -> SourceError { SourceError(code: .duplicateVersion, source: source, app: app, version: version) } - - static func changedID(_ identifier: String, previousID: String, source: Source) -> SourceError { SourceError(code: .changedID, source: source, sourceID: identifier, previousSourceID: previousID) } - static func duplicate(_ source: Source, previousSourceName: String?) -> SourceError { SourceError(code: .duplicate, source: source, previousSourceName: previousSourceName) } - - static func missingPermissionUsageDescription(for permission: any ALTAppPermission, app: StoreApp, source: Source) -> SourceError { - SourceError(code: .missingPermissionUsageDescription, source: source, app: app, permission: permission) - } -} - -struct SourceError: ALTLocalizedError -{ - let code: Code - var errorTitle: String? - var errorFailure: String? - - @Managed var source: Source - @Managed var app: StoreApp? - var bundleID: String? - var version: String? - - @UserInfoValue var previousSourceName: String? - - // Store in userInfo so they can be viewed from Error Log. - @UserInfoValue var sourceID: String? - @UserInfoValue var previousSourceID: String? - - @UserInfoValue - var permission: (any ALTAppPermission)? - - var errorFailureReason: String { - switch self.code - { - case .unsupported: return String(format: NSLocalizedString("The source “%@” is not supported by this version of AltStore.", comment: ""), self.$source.name) - case .duplicateBundleID: - let bundleIDFragment = self.bundleID.map { String(format: NSLocalizedString("the bundle identifier %@", comment: ""), $0) } ?? NSLocalizedString("the same bundle identifier", comment: "") - let failureReason = String(format: NSLocalizedString("The source “%@” contains multiple apps with %@.", comment: ""), self.$source.name, bundleIDFragment) - return failureReason - - case .duplicateVersion: - var versionFragment = NSLocalizedString("duplicate versions", comment: "") - if let version - { - versionFragment += " (\(version))" - } - - let appFragment: String - if let name = self.$app.name, let bundleID = self.$app.bundleIdentifier - { - appFragment = name + " (\(bundleID))" - } - else - { - appFragment = NSLocalizedString("one or more apps", comment: "") - } - - let failureReason = String(format: NSLocalizedString("The source “%@” contains %@ for %@.", comment: ""), self.$source.name, versionFragment, appFragment) - return failureReason - - case .changedID: - let failureReason = String(format: NSLocalizedString("The identifier of the source “%@” has changed.", comment: ""), self.$source.name) - return failureReason - - case .duplicate: - let baseMessage = String(format: NSLocalizedString("A source with the identifier '%@' already exists", comment: ""), self.$source.identifier) - guard let previousSourceName else { return baseMessage + "." } - - let failureReason = baseMessage + " (“\(previousSourceName)”)." - return failureReason - - case .missingPermissionUsageDescription: - let appName = self.$app.name ?? String(format: NSLocalizedString("an app in source “%@”", comment: ""), self.$source.name) - guard let permission else { - return String(format: NSLocalizedString("A permission for %@ is missing a usage description.", comment: ""), appName) - } - - let permissionType = permission.type.localizedName ?? NSLocalizedString("Permission", comment: "") - let failureReason = String(format: NSLocalizedString("The %@ '%@' for %@ is missing a usage description.", comment: ""), permissionType.lowercased(), permission.rawValue, appName) - return failureReason - } - } - - var recoverySuggestion: String? { - switch self.code - { - case .changedID: return NSLocalizedString("A source cannot change its identifier once added. This source can no longer be updated.", comment: "") - case .duplicate: - let failureReason = NSLocalizedString("Please remove the existing source in order to add this one.", comment: "") - return failureReason - - default: return nil - } - } -} - @objc(FetchSourceOperation) final class FetchSourceOperation: ResultOperation {