mirror of
https://github.com/SideStore/SideStore.git
synced 2026-02-17 18:53:40 +01:00
Create swift package
This commit is contained in:
128
Sources/Shared/Extensions/NSError+AltStore.swift
Normal file
128
Sources/Shared/Extensions/NSError+AltStore.swift
Normal file
@@ -0,0 +1,128 @@
|
||||
//
|
||||
// NSError+AltStore.swift
|
||||
// AltStore
|
||||
//
|
||||
// Created by Riley Testut on 3/11/20.
|
||||
// Copyright © 2020 Riley Testut. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
extension NSError {
|
||||
@objc(alt_localizedFailure)
|
||||
var localizedFailure: String? {
|
||||
let localizedFailure = (userInfo[NSLocalizedFailureErrorKey] as? String) ?? (NSError.userInfoValueProvider(forDomain: domain)?(self, NSLocalizedFailureErrorKey) as? String)
|
||||
return localizedFailure
|
||||
}
|
||||
|
||||
@objc(alt_localizedDebugDescription)
|
||||
var localizedDebugDescription: String? {
|
||||
let debugDescription = (userInfo[NSDebugDescriptionErrorKey] as? String) ?? (NSError.userInfoValueProvider(forDomain: domain)?(self, NSDebugDescriptionErrorKey) as? String)
|
||||
return debugDescription
|
||||
}
|
||||
|
||||
@objc(alt_errorWithLocalizedFailure:)
|
||||
func withLocalizedFailure(_ failure: String) -> NSError {
|
||||
var userInfo = self.userInfo
|
||||
userInfo[NSLocalizedFailureErrorKey] = failure
|
||||
|
||||
if let failureReason = localizedFailureReason {
|
||||
userInfo[NSLocalizedFailureReasonErrorKey] = failureReason
|
||||
} else if localizedFailure == nil && localizedFailureReason == nil && localizedDescription.contains(localizedErrorCode) {
|
||||
// Default localizedDescription, so replace with just the localized error code portion.
|
||||
userInfo[NSLocalizedFailureReasonErrorKey] = "(\(localizedErrorCode).)"
|
||||
} else {
|
||||
userInfo[NSLocalizedFailureReasonErrorKey] = localizedDescription
|
||||
}
|
||||
|
||||
if let localizedDescription = NSError.userInfoValueProvider(forDomain: domain)?(self, NSLocalizedDescriptionKey) as? String {
|
||||
userInfo[NSLocalizedDescriptionKey] = localizedDescription
|
||||
}
|
||||
|
||||
// Don't accidentally remove localizedDescription from dictionary
|
||||
// userInfo[NSLocalizedDescriptionKey] = NSError.userInfoValueProvider(forDomain: self.domain)?(self, NSLocalizedDescriptionKey) as? String
|
||||
|
||||
if let recoverySuggestion = localizedRecoverySuggestion {
|
||||
userInfo[NSLocalizedRecoverySuggestionErrorKey] = recoverySuggestion
|
||||
}
|
||||
|
||||
let error = NSError(domain: domain, code: code, userInfo: userInfo)
|
||||
return error
|
||||
}
|
||||
|
||||
func sanitizedForCoreData() -> NSError {
|
||||
var userInfo = self.userInfo
|
||||
userInfo[NSLocalizedFailureErrorKey] = localizedFailure
|
||||
userInfo[NSLocalizedDescriptionKey] = localizedDescription
|
||||
userInfo[NSLocalizedFailureReasonErrorKey] = localizedFailureReason
|
||||
userInfo[NSLocalizedRecoverySuggestionErrorKey] = localizedRecoverySuggestion
|
||||
|
||||
// Remove userInfo values that don't conform to NSSecureEncoding.
|
||||
userInfo = userInfo.filter { _, value in
|
||||
(value as AnyObject) is NSSecureCoding
|
||||
}
|
||||
|
||||
// Sanitize underlying errors.
|
||||
if let underlyingError = userInfo[NSUnderlyingErrorKey] as? Error {
|
||||
let sanitizedError = (underlyingError as NSError).sanitizedForCoreData()
|
||||
userInfo[NSUnderlyingErrorKey] = sanitizedError
|
||||
}
|
||||
|
||||
if #available(iOS 14.5, macOS 11.3, *), let underlyingErrors = userInfo[NSMultipleUnderlyingErrorsKey] as? [Error] {
|
||||
let sanitizedErrors = underlyingErrors.map { ($0 as NSError).sanitizedForCoreData() }
|
||||
userInfo[NSMultipleUnderlyingErrorsKey] = sanitizedErrors
|
||||
}
|
||||
|
||||
let error = NSError(domain: domain, code: code, userInfo: userInfo)
|
||||
return error
|
||||
}
|
||||
}
|
||||
|
||||
extension Error {
|
||||
var underlyingError: Error? {
|
||||
let underlyingError = (self as NSError).userInfo[NSUnderlyingErrorKey] as? Error
|
||||
return underlyingError
|
||||
}
|
||||
|
||||
var localizedErrorCode: String {
|
||||
let localizedErrorCode = String(format: NSLocalizedString("%@ error %@", comment: ""), (self as NSError).domain, (self as NSError).code as NSNumber)
|
||||
return localizedErrorCode
|
||||
}
|
||||
}
|
||||
|
||||
protocol ALTLocalizedError: LocalizedError, CustomNSError {
|
||||
var failure: String? { get }
|
||||
|
||||
var underlyingError: Error? { get }
|
||||
}
|
||||
|
||||
extension ALTLocalizedError {
|
||||
var errorUserInfo: [String: Any] {
|
||||
let userInfo = ([
|
||||
NSLocalizedDescriptionKey: errorDescription,
|
||||
NSLocalizedFailureReasonErrorKey: failureReason,
|
||||
NSLocalizedFailureErrorKey: failure,
|
||||
NSUnderlyingErrorKey: underlyingError
|
||||
] as [String: Any?]).compactMapValues { $0 }
|
||||
return userInfo
|
||||
}
|
||||
|
||||
var underlyingError: Error? {
|
||||
// Error's default implementation calls errorUserInfo,
|
||||
// but ALTLocalizedError.errorUserInfo calls underlyingError.
|
||||
// Return nil to prevent infinite recursion.
|
||||
nil
|
||||
}
|
||||
|
||||
var errorDescription: String? {
|
||||
guard let errorFailure = failure else { return (underlyingError as NSError?)?.localizedDescription }
|
||||
guard let failureReason = failureReason else { return errorFailure }
|
||||
|
||||
let errorDescription = errorFailure + " " + failureReason
|
||||
return errorDescription
|
||||
}
|
||||
|
||||
var failureReason: String? { (underlyingError as NSError?)?.localizedDescription }
|
||||
var recoverySuggestion: String? { (underlyingError as NSError?)?.localizedRecoverySuggestion }
|
||||
var helpAnchor: String? { (underlyingError as NSError?)?.helpAnchor }
|
||||
}
|
||||
Reference in New Issue
Block a user