From 2a392ddc44a24ebb7d670990eca6292d37012681 Mon Sep 17 00:00:00 2001 From: naturecodevoid <44983869+naturecodevoid@users.noreply.github.com> Date: Thu, 19 Jan 2023 07:52:47 -0800 Subject: [PATCH] SemVer version comparison --- .gitignore | 3 +- AltStore.xcodeproj/project.pbxproj | 27 ++++++++++++++++ .../xcshareddata/swiftpm/Package.resolved | 9 ++++++ .../AltStore 11.xcdatamodel/contents | 1 + AltStoreCore/Model/InstalledApp.swift | 32 +++++++++++++++++-- 5 files changed, 69 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index d750188a..2c932362 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ # macOS # *.DS_Store +._* # Xcode # @@ -33,4 +34,4 @@ xcuserdata /.vscode ## AppCode specific -.idea/ \ No newline at end of file +.idea/ diff --git a/AltStore.xcodeproj/project.pbxproj b/AltStore.xcodeproj/project.pbxproj index 4a46b7e7..92c94e88 100644 --- a/AltStore.xcodeproj/project.pbxproj +++ b/AltStore.xcodeproj/project.pbxproj @@ -21,6 +21,7 @@ 19B9B7452845E6DF0076EF69 /* SelectTeamViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19B9B7442845E6DF0076EF69 /* SelectTeamViewController.swift */; }; 4879A95F2861046500FC1BBD /* AltSign in Frameworks */ = {isa = PBXBuildFile; productRef = 4879A95E2861046500FC1BBD /* AltSign */; }; 4879A9622861049C00FC1BBD /* OpenSSL in Frameworks */ = {isa = PBXBuildFile; productRef = 4879A9612861049C00FC1BBD /* OpenSSL */; }; + 99C4EF4D2979132100CB538D /* SemanticVersion in Frameworks */ = {isa = PBXBuildFile; productRef = 99C4EF4C2979132100CB538D /* SemanticVersion */; }; B3146ED2284F581E00BBC3FD /* Roxas.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B3146ECD284F580500BBC3FD /* Roxas.framework */; }; B3146ED3284F581E00BBC3FD /* Roxas.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = B3146ECD284F580500BBC3FD /* Roxas.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; B33FFBA8295F8E98002259E6 /* libfragmentzip.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B343F894295F7F9B002B1159 /* libfragmentzip.a */; }; @@ -896,6 +897,7 @@ buildActionMask = 2147483647; files = ( B3C395F1284F2DE700DA9E2F /* KeychainAccess in Frameworks */, + 99C4EF4D2979132100CB538D /* SemanticVersion in Frameworks */, 4879A95F2861046500FC1BBD /* AltSign in Frameworks */, B39575F5284F29E20080B4FF /* Roxas.framework in Frameworks */, ); @@ -1937,11 +1939,13 @@ buildRules = ( ); dependencies = ( + 99C4EF51297994E200CB538D /* PBXTargetDependency */, ); name = AltStoreCore; packageProductDependencies = ( B3C395F0284F2DE700DA9E2F /* KeychainAccess */, 4879A95E2861046500FC1BBD /* AltSign */, + 99C4EF4C2979132100CB538D /* SemanticVersion */, ); productName = AltStoreCore; productReference = BF66EE7E2501AE50007EE018 /* AltStoreCore.framework */; @@ -2060,6 +2064,7 @@ B3C395FD284F3C0900DA9E2F /* XCRemoteSwiftPackageReference "STPrivilegedTask" */, 4879A95D2861046500FC1BBD /* XCRemoteSwiftPackageReference "AltSign" */, 4879A9602861049C00FC1BBD /* XCRemoteSwiftPackageReference "OpenSSL" */, + 99C4EF472978D52400CB538D /* XCRemoteSwiftPackageReference "SemanticVersion" */, ); productRefGroup = BFD2476B2284B9A500981D42 /* Products */; projectDirPath = ""; @@ -2543,6 +2548,10 @@ isa = PBXTargetDependency; productRef = 191E5FD9290AFA49001A3B7C /* OpenSSL */; }; + 99C4EF51297994E200CB538D /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + productRef = 99C4EF50297994E200CB538D /* SemanticVersion */; + }; B343F86F295F76FD002B1159 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = "minimuxer-staticlib"; @@ -3346,6 +3355,14 @@ minimumVersion = 1.1.180; }; }; + 99C4EF472978D52400CB538D /* XCRemoteSwiftPackageReference "SemanticVersion" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/SwiftPackageIndex/SemanticVersion.git"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 0.3.5; + }; + }; B3C395EF284F2DE700DA9E2F /* XCRemoteSwiftPackageReference "KeychainAccess" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/kishikawakatsumi/KeychainAccess.git"; @@ -3417,6 +3434,16 @@ package = 4879A9602861049C00FC1BBD /* XCRemoteSwiftPackageReference "OpenSSL" */; productName = OpenSSL; }; + 99C4EF4C2979132100CB538D /* SemanticVersion */ = { + isa = XCSwiftPackageProductDependency; + package = 99C4EF472978D52400CB538D /* XCRemoteSwiftPackageReference "SemanticVersion" */; + productName = SemanticVersion; + }; + 99C4EF50297994E200CB538D /* SemanticVersion */ = { + isa = XCSwiftPackageProductDependency; + package = 99C4EF472978D52400CB538D /* XCRemoteSwiftPackageReference "SemanticVersion" */; + productName = SemanticVersion; + }; B3C395F0284F2DE700DA9E2F /* KeychainAccess */ = { isa = XCSwiftPackageProductDependency; package = B3C395EF284F2DE700DA9E2F /* XCRemoteSwiftPackageReference "KeychainAccess" */; diff --git a/AltStore.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/AltStore.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index ce2c36c6..410b636e 100644 --- a/AltStore.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/AltStore.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -63,6 +63,15 @@ "version" : "1.10.1" } }, + { + "identity" : "semanticversion", + "kind" : "remoteSourceControl", + "location" : "https://github.com/SwiftPackageIndex/SemanticVersion.git", + "state" : { + "revision" : "fc670910dc0903cc269b3d0b776cda5703979c4e", + "version" : "0.3.5" + } + }, { "identity" : "sparkle", "kind" : "remoteSourceControl", diff --git a/AltStoreCore/Model/AltStore.xcdatamodeld/AltStore 11.xcdatamodel/contents b/AltStoreCore/Model/AltStore.xcdatamodeld/AltStore 11.xcdatamodel/contents index 72733b89..cceed50f 100644 --- a/AltStoreCore/Model/AltStore.xcdatamodeld/AltStore 11.xcdatamodel/contents +++ b/AltStoreCore/Model/AltStore.xcdatamodeld/AltStore 11.xcdatamodel/contents @@ -56,6 +56,7 @@ + diff --git a/AltStoreCore/Model/InstalledApp.swift b/AltStoreCore/Model/InstalledApp.swift index 3720c528..a27ce44f 100644 --- a/AltStoreCore/Model/InstalledApp.swift +++ b/AltStoreCore/Model/InstalledApp.swift @@ -10,6 +10,7 @@ import Foundation import CoreData import AltSign +import SemanticVersion // Free developer accounts are limited to only 3 active sideloaded apps at a time as of iOS 13.3.1. public let ALTActiveAppsLimit = 3 @@ -59,6 +60,33 @@ public class InstalledApp: NSManagedObject, InstalledAppProtocol return self.storeApp == nil } + @objc public var hasUpdate: Bool { + if self.storeApp == nil { return false } + if self.storeApp!.latestVersion == nil { return false } + + #if DEBUG + print("Comparing versions for app `\(self.bundleIdentifier)` between currentVersion `\(self.version)` and latestVersion `\(self.storeApp!.latestVersion!.version)`") + #endif + + let currentVersion = SemanticVersion(self.version) + let latestVersion = SemanticVersion(self.storeApp!.latestVersion!.version) + + if currentVersion == nil || latestVersion == nil { + #if DEBUG + print("One of the versions is not valid SemVer, using fallback method") + #endif + + // This should compare each character + return self.version < self.storeApp!.latestVersion!.version + } + + #if DEBUG + print("Both versions are valid SemVer, using SemVer comparison") + #endif + + return currentVersion! < latestVersion! + } + public var appIDCount: Int { return 1 + self.appExtensions.count } @@ -147,8 +175,8 @@ public extension InstalledApp class func updatesFetchRequest() -> NSFetchRequest { let fetchRequest = InstalledApp.fetchRequest() as NSFetchRequest - fetchRequest.predicate = NSPredicate(format: "%K == YES AND %K != nil AND %K != %K", - #keyPath(InstalledApp.isActive), #keyPath(InstalledApp.storeApp), #keyPath(InstalledApp.version), #keyPath(InstalledApp.storeApp.latestVersion.version)) + fetchRequest.predicate = NSPredicate(format: "%K == YES AND %K == YES", + #keyPath(InstalledApp.isActive), #keyPath(InstalledApp.hasUpdate)) return fetchRequest }