SemVer version comparison

This commit is contained in:
naturecodevoid
2023-01-19 07:52:47 -08:00
parent fa170bcf98
commit 2a392ddc44
5 changed files with 69 additions and 3 deletions

3
.gitignore vendored
View File

@@ -1,6 +1,7 @@
# macOS # macOS
# #
*.DS_Store *.DS_Store
._*
# Xcode # Xcode
# #
@@ -33,4 +34,4 @@ xcuserdata
/.vscode /.vscode
## AppCode specific ## AppCode specific
.idea/ .idea/

View File

@@ -21,6 +21,7 @@
19B9B7452845E6DF0076EF69 /* SelectTeamViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19B9B7442845E6DF0076EF69 /* SelectTeamViewController.swift */; }; 19B9B7452845E6DF0076EF69 /* SelectTeamViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19B9B7442845E6DF0076EF69 /* SelectTeamViewController.swift */; };
4879A95F2861046500FC1BBD /* AltSign in Frameworks */ = {isa = PBXBuildFile; productRef = 4879A95E2861046500FC1BBD /* AltSign */; }; 4879A95F2861046500FC1BBD /* AltSign in Frameworks */ = {isa = PBXBuildFile; productRef = 4879A95E2861046500FC1BBD /* AltSign */; };
4879A9622861049C00FC1BBD /* OpenSSL in Frameworks */ = {isa = PBXBuildFile; productRef = 4879A9612861049C00FC1BBD /* OpenSSL */; }; 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 */; }; 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, ); }; }; 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 */; }; B33FFBA8295F8E98002259E6 /* libfragmentzip.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B343F894295F7F9B002B1159 /* libfragmentzip.a */; };
@@ -896,6 +897,7 @@
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
B3C395F1284F2DE700DA9E2F /* KeychainAccess in Frameworks */, B3C395F1284F2DE700DA9E2F /* KeychainAccess in Frameworks */,
99C4EF4D2979132100CB538D /* SemanticVersion in Frameworks */,
4879A95F2861046500FC1BBD /* AltSign in Frameworks */, 4879A95F2861046500FC1BBD /* AltSign in Frameworks */,
B39575F5284F29E20080B4FF /* Roxas.framework in Frameworks */, B39575F5284F29E20080B4FF /* Roxas.framework in Frameworks */,
); );
@@ -1937,11 +1939,13 @@
buildRules = ( buildRules = (
); );
dependencies = ( dependencies = (
99C4EF51297994E200CB538D /* PBXTargetDependency */,
); );
name = AltStoreCore; name = AltStoreCore;
packageProductDependencies = ( packageProductDependencies = (
B3C395F0284F2DE700DA9E2F /* KeychainAccess */, B3C395F0284F2DE700DA9E2F /* KeychainAccess */,
4879A95E2861046500FC1BBD /* AltSign */, 4879A95E2861046500FC1BBD /* AltSign */,
99C4EF4C2979132100CB538D /* SemanticVersion */,
); );
productName = AltStoreCore; productName = AltStoreCore;
productReference = BF66EE7E2501AE50007EE018 /* AltStoreCore.framework */; productReference = BF66EE7E2501AE50007EE018 /* AltStoreCore.framework */;
@@ -2060,6 +2064,7 @@
B3C395FD284F3C0900DA9E2F /* XCRemoteSwiftPackageReference "STPrivilegedTask" */, B3C395FD284F3C0900DA9E2F /* XCRemoteSwiftPackageReference "STPrivilegedTask" */,
4879A95D2861046500FC1BBD /* XCRemoteSwiftPackageReference "AltSign" */, 4879A95D2861046500FC1BBD /* XCRemoteSwiftPackageReference "AltSign" */,
4879A9602861049C00FC1BBD /* XCRemoteSwiftPackageReference "OpenSSL" */, 4879A9602861049C00FC1BBD /* XCRemoteSwiftPackageReference "OpenSSL" */,
99C4EF472978D52400CB538D /* XCRemoteSwiftPackageReference "SemanticVersion" */,
); );
productRefGroup = BFD2476B2284B9A500981D42 /* Products */; productRefGroup = BFD2476B2284B9A500981D42 /* Products */;
projectDirPath = ""; projectDirPath = "";
@@ -2543,6 +2548,10 @@
isa = PBXTargetDependency; isa = PBXTargetDependency;
productRef = 191E5FD9290AFA49001A3B7C /* OpenSSL */; productRef = 191E5FD9290AFA49001A3B7C /* OpenSSL */;
}; };
99C4EF51297994E200CB538D /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
productRef = 99C4EF50297994E200CB538D /* SemanticVersion */;
};
B343F86F295F76FD002B1159 /* PBXTargetDependency */ = { B343F86F295F76FD002B1159 /* PBXTargetDependency */ = {
isa = PBXTargetDependency; isa = PBXTargetDependency;
name = "minimuxer-staticlib"; name = "minimuxer-staticlib";
@@ -3346,6 +3355,14 @@
minimumVersion = 1.1.180; 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" */ = { B3C395EF284F2DE700DA9E2F /* XCRemoteSwiftPackageReference "KeychainAccess" */ = {
isa = XCRemoteSwiftPackageReference; isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/kishikawakatsumi/KeychainAccess.git"; repositoryURL = "https://github.com/kishikawakatsumi/KeychainAccess.git";
@@ -3417,6 +3434,16 @@
package = 4879A9602861049C00FC1BBD /* XCRemoteSwiftPackageReference "OpenSSL" */; package = 4879A9602861049C00FC1BBD /* XCRemoteSwiftPackageReference "OpenSSL" */;
productName = 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 */ = { B3C395F0284F2DE700DA9E2F /* KeychainAccess */ = {
isa = XCSwiftPackageProductDependency; isa = XCSwiftPackageProductDependency;
package = B3C395EF284F2DE700DA9E2F /* XCRemoteSwiftPackageReference "KeychainAccess" */; package = B3C395EF284F2DE700DA9E2F /* XCRemoteSwiftPackageReference "KeychainAccess" */;

View File

@@ -63,6 +63,15 @@
"version" : "1.10.1" "version" : "1.10.1"
} }
}, },
{
"identity" : "semanticversion",
"kind" : "remoteSourceControl",
"location" : "https://github.com/SwiftPackageIndex/SemanticVersion.git",
"state" : {
"revision" : "fc670910dc0903cc269b3d0b776cda5703979c4e",
"version" : "0.3.5"
}
},
{ {
"identity" : "sparkle", "identity" : "sparkle",
"kind" : "remoteSourceControl", "kind" : "remoteSourceControl",

View File

@@ -56,6 +56,7 @@
<attribute name="certificateSerialNumber" optional="YES" attributeType="String"/> <attribute name="certificateSerialNumber" optional="YES" attributeType="String"/>
<attribute name="expirationDate" attributeType="Date" usesScalarValueType="NO"/> <attribute name="expirationDate" attributeType="Date" usesScalarValueType="NO"/>
<attribute name="hasAlternateIcon" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/> <attribute name="hasAlternateIcon" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
<attribute name="hasUpdate" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
<attribute name="installedDate" attributeType="Date" usesScalarValueType="NO"/> <attribute name="installedDate" attributeType="Date" usesScalarValueType="NO"/>
<attribute name="isActive" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES"/> <attribute name="isActive" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES"/>
<attribute name="isRefreshing" transient="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/> <attribute name="isRefreshing" transient="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>

View File

@@ -10,6 +10,7 @@ import Foundation
import CoreData import CoreData
import AltSign import AltSign
import SemanticVersion
// Free developer accounts are limited to only 3 active sideloaded apps at a time as of iOS 13.3.1. // Free developer accounts are limited to only 3 active sideloaded apps at a time as of iOS 13.3.1.
public let ALTActiveAppsLimit = 3 public let ALTActiveAppsLimit = 3
@@ -59,6 +60,33 @@ public class InstalledApp: NSManagedObject, InstalledAppProtocol
return self.storeApp == nil 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 { public var appIDCount: Int {
return 1 + self.appExtensions.count return 1 + self.appExtensions.count
} }
@@ -147,8 +175,8 @@ public extension InstalledApp
class func updatesFetchRequest() -> NSFetchRequest<InstalledApp> class func updatesFetchRequest() -> NSFetchRequest<InstalledApp>
{ {
let fetchRequest = InstalledApp.fetchRequest() as NSFetchRequest<InstalledApp> let fetchRequest = InstalledApp.fetchRequest() as NSFetchRequest<InstalledApp>
fetchRequest.predicate = NSPredicate(format: "%K == YES AND %K != nil AND %K != %K", fetchRequest.predicate = NSPredicate(format: "%K == YES AND %K == YES",
#keyPath(InstalledApp.isActive), #keyPath(InstalledApp.storeApp), #keyPath(InstalledApp.version), #keyPath(InstalledApp.storeApp.latestVersion.version)) #keyPath(InstalledApp.isActive), #keyPath(InstalledApp.hasUpdate))
return fetchRequest return fetchRequest
} }