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
}