[Shared] Adds @UserInfoValue property wrapper for ALTLocalizedErrors

ALTLocalizedErrors now automatically include all properties annotated with @UserInfoValue in userInfo when bridged to NSError.
This commit is contained in:
Riley Testut
2023-05-11 14:29:45 -05:00
committed by Magesh K
parent ea506b904d
commit 5b275d6811
3 changed files with 63 additions and 2 deletions

View File

@@ -341,6 +341,8 @@
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 */; };
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 */; };
D51AD27E29356B7B00967AAA /* ALTWrappedError.h in Headers */ = {isa = PBXBuildFile; fileRef = D51AD27C29356B7B00967AAA /* ALTWrappedError.h */; settings = {ATTRIBUTES = (Public, ); }; };
D51AD27F29356B7B00967AAA /* ALTWrappedError.m in Sources */ = {isa = PBXBuildFile; fileRef = D51AD27D29356B7B00967AAA /* ALTWrappedError.m */; };
@@ -897,6 +899,7 @@
D52C08ED28AEC37A006C4AE5 /* AppVersion.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppVersion.swift; sourceTree = "<group>"; };
D52E988928D002D30032BE6B /* AltStore 11.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "AltStore 11.xcdatamodel"; sourceTree = "<group>"; };
C9EEAA842DA87A88A870053B /* Pods_AltStore.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_AltStore.framework; sourceTree = BUILT_PRODUCTS_DIR; };
D5189C002A01BC6800F44625 /* UserInfoValue.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserInfoValue.swift; sourceTree = "<group>"; };
D51AD27C29356B7B00967AAA /* ALTWrappedError.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALTWrappedError.h; sourceTree = "<group>"; };
D51AD27D29356B7B00967AAA /* ALTWrappedError.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALTWrappedError.m; sourceTree = "<group>"; };
D52C08ED28AEC37A006C4AE5 /* AppVersion.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppVersion.swift; sourceTree = "<group>"; };
@@ -1936,6 +1939,7 @@
isa = PBXGroup;
children = (
D5DB145828F9DC1000A8F606 /* ALTLocalizedError.swift */,
D5189C002A01BC6800F44625 /* UserInfoValue.swift */,
D51AD27C29356B7B00967AAA /* ALTWrappedError.h */,
D51AD27D29356B7B00967AAA /* ALTWrappedError.m */,
);
@@ -2472,6 +2476,7 @@
BFECAC8224FD950B0077C41F /* ServerProtocol.swift in Sources */,
BFECAC8124FD950B0077C41F /* ALTServerError+Conveniences.swift in Sources */,
BFECAC7F24FD950B0077C41F /* CodableError.swift in Sources */,
D5189C012A01BC6800F44625 /* UserInfoValue.swift in Sources */,
D51AD28029356B8000967AAA /* ALTWrappedError.m in Sources */,
BFECAC8624FD950B0077C41F /* Result+Conveniences.swift in Sources */,
BF265D1925F843A000080DC9 /* NSError+AltStore.swift in Sources */,
@@ -2590,6 +2595,7 @@
BF66EED32501AECA007EE018 /* AltStore2ToAltStore3.xcmappingmodel in Sources */,
BF66EEA52501AEC5007EE018 /* Benefit.swift in Sources */,
BF66EED22501AECA007EE018 /* AltStore4ToAltStore5.xcmappingmodel in Sources */,
D5189C022A01BC6800F44625 /* UserInfoValue.swift in Sources */,
BFAECC5B2501B0A400528F27 /* Bundle+AltStore.swift in Sources */,
BF66EECD2501AECA007EE018 /* StoreAppPolicy.swift in Sources */,
BF66EEE82501AED0007EE018 /* UserDefaults+AltStore.swift in Sources */,

View File

@@ -69,13 +69,15 @@ public extension ALTLocalizedError
}
var errorUserInfo: [String : Any] {
let userInfo: [String: Any?] = [
var userInfo: [String: Any?] = [
NSLocalizedFailureErrorKey: self.errorFailure,
ALTLocalizedTitleErrorKey: self.errorTitle,
// ALTSourceFileErrorKey: self.sourceFile, // TODO: Figure out where these come from
// ALTSourceLineErrorKey: self.sourceLine,
]
userInfo.merge(self.userInfoValues) { (_, new) in new }
return userInfo.compactMapValues { $0 }
}
@@ -125,6 +127,21 @@ public extension ALTLocalizedError
}
}
private extension ALTLocalizedError
{
var userInfoValues: [(String, Any)] {
let userInfoValues = Mirror(reflecting: self).children.compactMap { (label, value) -> (String, Any)? in
guard let userInfoValue = value as? any UserInfoValueProtocol,
let key: any StringProtocol = userInfoValue.key ?? label?.dropFirst() // Remove leading underscore
else { return nil }
return (String(key), userInfoValue.wrappedValue)
}
return userInfoValues
}
}
public struct DefaultLocalizedError<Code: ALTErrorEnum>: ALTLocalizedError
{
public let code: Code

View File

@@ -0,0 +1,38 @@
//
// UserInfoValue.swift
// AltStore
//
// Created by Riley Testut on 5/2/23.
// Copyright © 2023 Riley Testut. All rights reserved.
//
import Foundation
protocol UserInfoValueProtocol<Value>
{
associatedtype Value
var key: String? { get }
var wrappedValue: Value { get }
}
@propertyWrapper
public struct UserInfoValue<Value>: UserInfoValueProtocol
{
public let key: String?
public var wrappedValue: Value
// Necessary for memberwise initializers to work as expected
// https://github.com/apple/swift-evolution/blob/main/proposals/0258-property-wrappers.md#memberwise-initializers
public init(wrappedValue: Value)
{
self.wrappedValue = wrappedValue
self.key = nil
}
public init(wrappedValue: Value, key: String)
{
self.wrappedValue = wrappedValue
self.key = key
}
}