2022-09-08 16:14:28 -05:00
|
|
|
//
|
|
|
|
|
// LoggedError.swift
|
|
|
|
|
// AltStoreCore
|
|
|
|
|
//
|
|
|
|
|
// Created by Riley Testut on 9/6/22.
|
|
|
|
|
// Copyright © 2022 Riley Testut. All rights reserved.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
import CoreData
|
|
|
|
|
|
|
|
|
|
extension LoggedError
|
|
|
|
|
{
|
|
|
|
|
public enum Operation: String
|
|
|
|
|
{
|
|
|
|
|
case install
|
|
|
|
|
case update
|
|
|
|
|
case refresh
|
|
|
|
|
case activate
|
|
|
|
|
case deactivate
|
|
|
|
|
case backup
|
|
|
|
|
case restore
|
2024-08-06 10:43:52 +09:00
|
|
|
case connection
|
|
|
|
|
case enableJIT
|
2022-09-08 16:14:28 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@objc(LoggedError)
|
|
|
|
|
public class LoggedError: NSManagedObject, Fetchable
|
|
|
|
|
{
|
|
|
|
|
/* Properties */
|
|
|
|
|
@NSManaged public private(set) var date: Date
|
|
|
|
|
|
|
|
|
|
@nonobjc public var operation: Operation? {
|
|
|
|
|
guard let rawOperation = self._operation else { return nil }
|
|
|
|
|
|
|
|
|
|
let operation = Operation(rawValue: rawOperation)
|
|
|
|
|
return operation
|
|
|
|
|
}
|
|
|
|
|
@NSManaged @objc(operation) private var _operation: String?
|
|
|
|
|
|
|
|
|
|
@NSManaged public private(set) var domain: String
|
|
|
|
|
@NSManaged public private(set) var code: Int32
|
|
|
|
|
@NSManaged public private(set) var userInfo: [String: Any]
|
|
|
|
|
|
|
|
|
|
@NSManaged public private(set) var appName: String
|
|
|
|
|
@NSManaged public private(set) var appBundleID: String
|
|
|
|
|
|
|
|
|
|
/* Relationships */
|
|
|
|
|
@NSManaged public private(set) var storeApp: StoreApp?
|
|
|
|
|
@NSManaged public private(set) var installedApp: InstalledApp?
|
|
|
|
|
|
|
|
|
|
private static let dateFormatter: DateFormatter = {
|
|
|
|
|
let dateFormatter = DateFormatter()
|
|
|
|
|
dateFormatter.dateStyle = .long
|
|
|
|
|
dateFormatter.timeStyle = .none
|
|
|
|
|
return dateFormatter
|
|
|
|
|
}()
|
|
|
|
|
|
|
|
|
|
private override init(entity: NSEntityDescription, insertInto context: NSManagedObjectContext?)
|
|
|
|
|
{
|
|
|
|
|
super.init(entity: entity, insertInto: context)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public init(error: Error, app: AppProtocol, date: Date = Date(), operation: Operation? = nil, context: NSManagedObjectContext)
|
|
|
|
|
{
|
|
|
|
|
super.init(entity: LoggedError.entity(), insertInto: context)
|
|
|
|
|
|
|
|
|
|
self.date = date
|
|
|
|
|
self._operation = operation?.rawValue
|
|
|
|
|
|
2024-08-06 10:43:52 +09:00
|
|
|
let nsError: NSError
|
|
|
|
|
if let error = error as? ALTServerError, error.code == .underlyingError, let underlyingError = error.underlyingError {
|
|
|
|
|
nsError = underlyingError as NSError
|
|
|
|
|
} else {
|
|
|
|
|
nsError = error as NSError
|
|
|
|
|
}
|
2022-09-08 16:14:28 -05:00
|
|
|
self.domain = nsError.domain
|
|
|
|
|
self.code = Int32(nsError.code)
|
|
|
|
|
self.userInfo = nsError.userInfo
|
|
|
|
|
|
|
|
|
|
self.appName = app.name
|
|
|
|
|
self.appBundleID = app.bundleIdentifier
|
|
|
|
|
|
|
|
|
|
switch app
|
|
|
|
|
{
|
|
|
|
|
case let storeApp as StoreApp: self.storeApp = storeApp
|
|
|
|
|
case let installedApp as InstalledApp: self.installedApp = installedApp
|
2022-11-16 18:11:28 -06:00
|
|
|
case let appVersion as AppVersion:
|
|
|
|
|
if let installedApp = appVersion.app?.installedApp
|
|
|
|
|
{
|
|
|
|
|
self.installedApp = installedApp
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
self.storeApp = appVersion.app
|
|
|
|
|
}
|
|
|
|
|
|
2022-09-08 16:14:28 -05:00
|
|
|
default: break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public extension LoggedError
|
|
|
|
|
{
|
|
|
|
|
var app: AppProtocol {
|
|
|
|
|
// `as AppProtocol` needed to fix "cannot convert AnyApp to StoreApp" compiler error with Xcode 14.
|
|
|
|
|
let app = self.installedApp ?? self.storeApp ?? AnyApp(name: self.appName, bundleIdentifier: self.appBundleID, url: nil) as AppProtocol
|
|
|
|
|
return app
|
|
|
|
|
}
|
|
|
|
|
|
2024-08-06 10:43:52 +09:00
|
|
|
var error: NSError {
|
2022-09-08 16:14:28 -05:00
|
|
|
let nsError = NSError(domain: self.domain, code: Int(self.code), userInfo: self.userInfo)
|
|
|
|
|
return nsError
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@objc
|
|
|
|
|
var localizedDateString: String {
|
|
|
|
|
let localizedDateString = LoggedError.dateFormatter.string(from: self.date)
|
|
|
|
|
return localizedDateString
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var localizedFailure: String? {
|
|
|
|
|
guard let operation = self.operation else { return nil }
|
|
|
|
|
switch operation
|
|
|
|
|
{
|
|
|
|
|
case .install: return String(format: NSLocalizedString("Install %@ Failed", comment: ""), self.appName)
|
|
|
|
|
case .update: return String(format: NSLocalizedString("Update %@ Failed", comment: ""), self.appName)
|
|
|
|
|
case .refresh: return String(format: NSLocalizedString("Refresh %@ Failed", comment: ""), self.appName)
|
|
|
|
|
case .activate: return String(format: NSLocalizedString("Activate %@ Failed", comment: ""), self.appName)
|
|
|
|
|
case .deactivate: return String(format: NSLocalizedString("Deactivate %@ Failed", comment: ""), self.appName)
|
|
|
|
|
case .backup: return String(format: NSLocalizedString("Backup %@ Failed", comment: ""), self.appName)
|
|
|
|
|
case .restore: return String(format: NSLocalizedString("Restore %@ Failed", comment: ""), self.appName)
|
2024-08-06 10:43:52 +09:00
|
|
|
case .connection: return String(format: NSLocalizedString("Connection during %@ Failed", comment: ""), self.appName)
|
|
|
|
|
case .enableJIT: return String(format: NSLocalizedString("Enabling JIT for %@ Failed", comment: ""), self.appName)
|
2022-09-08 16:14:28 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public extension LoggedError
|
|
|
|
|
{
|
|
|
|
|
@nonobjc class func fetchRequest() -> NSFetchRequest<LoggedError>
|
|
|
|
|
{
|
|
|
|
|
return NSFetchRequest<LoggedError>(entityName: "LoggedError")
|
|
|
|
|
}
|
|
|
|
|
}
|