mirror of
https://github.com/SideStore/SideStore.git
synced 2026-02-09 06:43:25 +01:00
[AltStoreCore] Flattens optional values when @Managed/@AsyncManaged.wrappedValue is also optional
This commit is contained in:
@@ -357,6 +357,7 @@
|
||||
D561B2ED28EF5A4F006752E4 /* AltSign-Dynamic in Embed Frameworks */ = {isa = PBXBuildFile; productRef = D561B2EA28EF5A4F006752E4 /* AltSign-Dynamic */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||
D5708417292448DA00D42D34 /* OperatingSystemVersion+Comparable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5708416292448DA00D42D34 /* OperatingSystemVersion+Comparable.swift */; };
|
||||
D570841A2924680D00D42D34 /* OperatingSystemVersion+Comparable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5708416292448DA00D42D34 /* OperatingSystemVersion+Comparable.swift */; };
|
||||
D5728CA72A0D79D30014E73C /* OptionalProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5728CA62A0D79D30014E73C /* OptionalProtocol.swift */; };
|
||||
D57968CB29CB99EF00539069 /* VibrantButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = D57968CA29CB99EF00539069 /* VibrantButton.swift */; };
|
||||
D57DF638271E32F000677701 /* PatchApp.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D57DF637271E32F000677701 /* PatchApp.storyboard */; };
|
||||
D57DF63F271E51E400677701 /* ALTAppPatcher.m in Sources */ = {isa = PBXBuildFile; fileRef = D57DF63E271E51E400677701 /* ALTAppPatcher.m */; };
|
||||
@@ -912,6 +913,7 @@
|
||||
D54DED1328CBC44B008B27A0 /* ErrorLogTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ErrorLogTableViewCell.swift; sourceTree = "<group>"; };
|
||||
D55E163528776CB000A627A1 /* ComplicationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComplicationView.swift; sourceTree = "<group>"; };
|
||||
D5708416292448DA00D42D34 /* OperatingSystemVersion+Comparable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "OperatingSystemVersion+Comparable.swift"; sourceTree = "<group>"; };
|
||||
D5728CA62A0D79D30014E73C /* OptionalProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OptionalProtocol.swift; sourceTree = "<group>"; };
|
||||
D57968CA29CB99EF00539069 /* VibrantButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VibrantButton.swift; sourceTree = "<group>"; };
|
||||
D57DF637271E32F000677701 /* PatchApp.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = PatchApp.storyboard; sourceTree = "<group>"; };
|
||||
D57DF63D271E51E400677701 /* ALTAppPatcher.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALTAppPatcher.h; sourceTree = "<group>"; };
|
||||
@@ -1439,6 +1441,7 @@
|
||||
children = (
|
||||
BF66EE9B2501AEC1007EE018 /* AppProtocol.swift */,
|
||||
BF66EE9C2501AEC1007EE018 /* Fetchable.swift */,
|
||||
D5728CA62A0D79D30014E73C /* OptionalProtocol.swift */,
|
||||
);
|
||||
path = Protocols;
|
||||
sourceTree = "<group>";
|
||||
@@ -2636,6 +2639,7 @@
|
||||
BF66EEEB2501AED0007EE018 /* UIApplication+AppExtension.swift in Sources */,
|
||||
D5F48B4829CCF21B002B52A4 /* AltStore+Async.swift in Sources */,
|
||||
BF66EED92501AECA007EE018 /* Team.swift in Sources */,
|
||||
D5728CA72A0D79D30014E73C /* OptionalProtocol.swift in Sources */,
|
||||
BF66EED12501AECA007EE018 /* AltStore3ToAltStore4.xcmappingmodel in Sources */,
|
||||
D5F48B4C29CD0C48002B52A4 /* AsyncManaged.swift in Sources */,
|
||||
BFAECC5C2501B0A400528F27 /* CFNotificationName+AltStore.m in Sources */,
|
||||
|
||||
19
AltStoreCore/Protocols/OptionalProtocol.swift
Normal file
19
AltStoreCore/Protocols/OptionalProtocol.swift
Normal file
@@ -0,0 +1,19 @@
|
||||
//
|
||||
// OptionalProtocol.swift
|
||||
// AltStoreCore
|
||||
//
|
||||
// Created by Riley Testut on 5/11/23.
|
||||
// Copyright © 2023 Riley Testut. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
// Public so we can use as generic constraint.
|
||||
public protocol OptionalProtocol
|
||||
{
|
||||
associatedtype Wrapped
|
||||
|
||||
static var none: Self { get }
|
||||
}
|
||||
|
||||
extension Optional: OptionalProtocol {}
|
||||
@@ -71,6 +71,7 @@ public extension AsyncManaged
|
||||
/// @dynamicMemberLookup
|
||||
public extension AsyncManaged
|
||||
{
|
||||
// Non-optional values
|
||||
subscript<T>(dynamicMember keyPath: KeyPath<ManagedObject, T>) -> T {
|
||||
get async {
|
||||
let result = await self.perform { $0[keyPath: keyPath] }
|
||||
@@ -78,7 +79,7 @@ public extension AsyncManaged
|
||||
}
|
||||
}
|
||||
|
||||
// Optionals
|
||||
// Optional wrapped value
|
||||
subscript<Wrapped, T>(dynamicMember keyPath: KeyPath<Wrapped, T>) -> T? where ManagedObject == Optional<Wrapped> {
|
||||
get async {
|
||||
guard let wrappedValue else { return nil }
|
||||
@@ -87,4 +88,14 @@ public extension AsyncManaged
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
// Optional wrapped value + optional property (flattened)
|
||||
subscript<Wrapped, T>(dynamicMember keyPath: KeyPath<Wrapped, T>) -> T where ManagedObject == Optional<Wrapped>, T: OptionalProtocol {
|
||||
get async {
|
||||
guard let wrappedValue else { return T.none }
|
||||
|
||||
let result = await self.perform { _ in wrappedValue[keyPath: keyPath] }
|
||||
return result
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,13 +80,14 @@ public extension Managed
|
||||
/// @dynamicMemberLookup
|
||||
public extension Managed
|
||||
{
|
||||
// Non-optional values
|
||||
subscript<T>(dynamicMember keyPath: KeyPath<ManagedObject, T>) -> T
|
||||
{
|
||||
let result = self.perform { $0[keyPath: keyPath] }
|
||||
return result
|
||||
}
|
||||
|
||||
// Optionals
|
||||
// Optional wrapped value
|
||||
subscript<Wrapped, T>(dynamicMember keyPath: KeyPath<Wrapped, T>) -> T? where ManagedObject == Optional<Wrapped>
|
||||
{
|
||||
guard let wrappedValue else { return nil }
|
||||
@@ -94,4 +95,13 @@ public extension Managed
|
||||
let result = self.perform { _ in wrappedValue[keyPath: keyPath] }
|
||||
return result
|
||||
}
|
||||
|
||||
// Optional wrapped value + optional property (flattened)
|
||||
subscript<Wrapped, T>(dynamicMember keyPath: KeyPath<Wrapped, T>) -> T where ManagedObject == Optional<Wrapped>, T: OptionalProtocol
|
||||
{
|
||||
guard let wrappedValue else { return T.none }
|
||||
|
||||
let result = self.perform { _ in wrappedValue[keyPath: keyPath] }
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user