diff --git a/AltStore.xcodeproj/project.pbxproj b/AltStore.xcodeproj/project.pbxproj index 5cc9af4f..cfdd2098 100644 --- a/AltStore.xcodeproj/project.pbxproj +++ b/AltStore.xcodeproj/project.pbxproj @@ -10,6 +10,7 @@ 03F06CD52942C27E001C4D68 /* Bundle+AltStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF1E314122A05D4C00370A3C /* Bundle+AltStore.swift */; }; 0E05025A2BEC83C500879B5C /* OperatingSystemVersion+Comparable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E0502592BEC83C500879B5C /* OperatingSystemVersion+Comparable.swift */; }; 0E05025C2BEC947000879B5C /* String+SideStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E05025B2BEC947000879B5C /* String+SideStore.swift */; }; + 0E13E5862CC8F55900E9C0DF /* ProcessInfo+SideStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E13E5852CC8F55900E9C0DF /* ProcessInfo+SideStore.swift */; }; 0E1A1F912AE36A9700364CAD /* bytearray.c in Sources */ = {isa = PBXBuildFile; fileRef = 0E1A1F902AE36A9600364CAD /* bytearray.c */; }; 0E764E172ADFF5740043DD4E /* AltBackup.ipa in Resources */ = {isa = PBXBuildFile; fileRef = 0E764E162ADFF5740043DD4E /* AltBackup.ipa */; }; 0EA1665B2ADFE0D2003015C1 /* out-limd.c in Sources */ = {isa = PBXBuildFile; fileRef = 0EA166472ADFE0D1003015C1 /* out-limd.c */; }; @@ -509,6 +510,7 @@ /* Begin PBXFileReference section */ 0E0502592BEC83C500879B5C /* OperatingSystemVersion+Comparable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "OperatingSystemVersion+Comparable.swift"; sourceTree = ""; }; 0E05025B2BEC947000879B5C /* String+SideStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+SideStore.swift"; sourceTree = ""; }; + 0E13E5852CC8F55900E9C0DF /* ProcessInfo+SideStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ProcessInfo+SideStore.swift"; sourceTree = ""; }; 0E1A1F902AE36A9600364CAD /* bytearray.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = bytearray.c; path = src/bytearray.c; sourceTree = ""; }; 0E764E162ADFF5740043DD4E /* AltBackup.ipa */ = {isa = PBXFileReference; lastKnownFileType = file; name = AltBackup.ipa; path = AltStore/Resources/AltBackup.ipa; sourceTree = SOURCE_ROOT; }; 0EA166412ADFE0D1003015C1 /* jplist.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = jplist.c; path = Dependencies/libplist/src/jplist.c; sourceTree = SOURCE_ROOT; }; @@ -1678,6 +1680,7 @@ BFE00A1F2503097F00EB4D0C /* INInteraction+AltStore.swift */, D57F2C9326E01BC700B9FA39 /* UIDevice+Vibration.swift */, B376FE3D29258C8900E18883 /* OSLog+SideStore.swift */, + 0E13E5852CC8F55900E9C0DF /* ProcessInfo+SideStore.swift */, ); path = Extensions; sourceTree = ""; @@ -2552,6 +2555,7 @@ BF770E5822BC3D0F002A40FE /* RefreshGroup.swift in Sources */, 19B9B7452845E6DF0076EF69 /* SelectTeamViewController.swift in Sources */, 99F87D0529D8B4E200B40039 /* minimuxer-helpers.swift in Sources */, + 0E13E5862CC8F55900E9C0DF /* ProcessInfo+SideStore.swift in Sources */, BF18B0F122E25DF9005C4CF5 /* ToastView.swift in Sources */, BF3D649F22E7B24C00E9056B /* CollapsingTextView.swift in Sources */, BF02419622F2199300129732 /* RefreshAttemptsViewController.swift in Sources */, diff --git a/AltStore/Extensions/ProcessInfo+SideStore.swift b/AltStore/Extensions/ProcessInfo+SideStore.swift new file mode 100644 index 00000000..7cb13e63 --- /dev/null +++ b/AltStore/Extensions/ProcessInfo+SideStore.swift @@ -0,0 +1,96 @@ +// +// ProcessInfo+SideStore.swift +// SideStore +// +// Created by ny on 10/23/24. +// Copyright © 2024 SideStore. All rights reserved. +// + +import Foundation + +fileprivate struct BuildVersion: Comparable { + let prefix: String + let numericPart: Int + let suffix: Character? + + init?(_ buildString: String) { + // Initialize indices + var index = buildString.startIndex + + // Extract prefix (letters before the numeric part) + while index < buildString.endIndex, !buildString[index].isNumber { + index = buildString.index(after: index) + } + guard index > buildString.startIndex else { return nil } + self.prefix = String(buildString[buildString.startIndex.. Bool { + // Compare prefixes + if lhs.prefix != rhs.prefix { + return lhs.prefix < rhs.prefix + } + // Compare numeric parts + if lhs.numericPart != rhs.numericPart { + return lhs.numericPart < rhs.numericPart + } + // Compare suffixes + switch (lhs.suffix, rhs.suffix) { + case let (l?, r?): + return l < r + case (nil, _?): + return true // nil is considered less than any character + case (_?, nil): + return false + default: + return false // Both are nil and equal + } + } + + static func == (lhs: BuildVersion, rhs: BuildVersion) -> Bool { + return lhs.prefix == rhs.prefix && + lhs.numericPart == rhs.numericPart && + lhs.suffix == rhs.suffix + } +} + +extension ProcessInfo { + var shortVersion: String { + operatingSystemVersionString + .replacingOccurrences(of: "Version ", with: "") + .replacingOccurrences(of: "Build ", with: "") + } + + var operatingSystemBuild: String { + if let start = shortVersion.range(of: "(")?.upperBound, + let end = shortVersion.range(of: ")")?.lowerBound { + shortVersion[start..= OperatingSystemVersion(majorVersion: 18, minorVersion: 1, patchVersion: 1) { true } + else if operatingSystemVersion <= OperatingSystemVersion(majorVersion: 18, minorVersion: 1, patchVersion: 0) { false } + else if operatingSystemVersion >= OperatingSystemVersion(majorVersion: 18, minorVersion: 1, patchVersion: 0), + let currentBuild = BuildVersion(operatingSystemBuild), + let targetBuild = BuildVersion("22B5054e") { + currentBuild > targetBuild + } else { false } + } +} diff --git a/AltStore/Settings/SettingsViewController.swift b/AltStore/Settings/SettingsViewController.swift index f69b033f..45e88f0f 100644 --- a/AltStore/Settings/SettingsViewController.swift +++ b/AltStore/Settings/SettingsViewController.swift @@ -39,13 +39,8 @@ extension SettingsViewController static var allCases: [AppRefreshRow] { var c: [AppRefreshRow] = [.backgroundRefresh, .noIdleTimeout] - let low: OperatingSystemVersion = .init(majorVersion: 14, minorVersion: 0, patchVersion: 0) - let high: OperatingSystemVersion = .init(majorVersion: 18, minorVersion: 2, patchVersion: 0) - let current = ProcessInfo.processInfo.operatingSystemVersion - if UserDefaults.standard.isDebugModeEnabled, low <= current, current < high { - c.append(.disableAppLimit) - } guard #available(iOS 14, *) else { return c } + if !ProcessInfo().sparseRestorePatched { c.append(.disableAppLimit) } c.append(.addToSiri) return c }