mirror of
https://github.com/SideStore/SideStore.git
synced 2026-02-08 22:33:26 +01:00
Merge pull request #920 from mahee96/develop
Migration: Fixes for migration issues when migrating from 0.5.9 to 0.6.0
This commit is contained in:
@@ -59,6 +59,15 @@
|
||||
A80D60D32D3DD85100CEF65D /* ReleaseTrack.swift in Sources */ = {isa = PBXBuildFile; fileRef = A80D60D12D3D705F00CEF65D /* ReleaseTrack.swift */; };
|
||||
A80D790D2D2F20AF00A40F40 /* PaginationIntent.swift in Sources */ = {isa = PBXBuildFile; fileRef = A80D790C2D2F20AF00A40F40 /* PaginationIntent.swift */; };
|
||||
A80D790F2D2F217000A40F40 /* PaginationDataHolder.swift in Sources */ = {isa = PBXBuildFile; fileRef = A80D790E2D2F217000A40F40 /* PaginationDataHolder.swift */; };
|
||||
A815AA952D90D2A100929A9E /* StoreApp17To17_1MigrationPolicy.swift in Sources */ = {isa = PBXBuildFile; fileRef = A815AA942D90D2A100929A9E /* StoreApp17To17_1MigrationPolicy.swift */; };
|
||||
A815AA972D90E16400929A9E /* ReleaseTrack17To17_1MigrationPolicy.swift in Sources */ = {isa = PBXBuildFile; fileRef = A815AA962D90E16400929A9E /* ReleaseTrack17To17_1MigrationPolicy.swift */; };
|
||||
A815AA992D90E5E500929A9E /* AltStore17ToAltStore17_1.xcmappingmodel in Sources */ = {isa = PBXBuildFile; fileRef = A815AA982D90E5E500929A9E /* AltStore17ToAltStore17_1.xcmappingmodel */; };
|
||||
A815AA9F2D9104DD00929A9E /* BuildInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = A815AA9E2D9104DD00929A9E /* BuildInfo.swift */; };
|
||||
A815AAA12D9108BC00929A9E /* AltStore11ToAltStore17_1.xcmappingmodel in Sources */ = {isa = PBXBuildFile; fileRef = A815AAA02D9108BC00929A9E /* AltStore11ToAltStore17_1.xcmappingmodel */; };
|
||||
A815AAA72D9108CB00929A9E /* ReleaseTrack11To17_1MigrationPolicy.swift in Sources */ = {isa = PBXBuildFile; fileRef = A815AAA42D9108CB00929A9E /* ReleaseTrack11To17_1MigrationPolicy.swift */; };
|
||||
A815AAA82D9108CB00929A9E /* AppPermission11To17_1MigrationPolicy.swift in Sources */ = {isa = PBXBuildFile; fileRef = A815AAA52D9108CB00929A9E /* AppPermission11To17_1MigrationPolicy.swift */; };
|
||||
A815AAA92D9108CB00929A9E /* Source11To17_1MigrationPolicy.swift in Sources */ = {isa = PBXBuildFile; fileRef = A815AAA22D9108CB00929A9E /* Source11To17_1MigrationPolicy.swift */; };
|
||||
A815AAAA2D9108CB00929A9E /* StoreApp11To17_1MigrationPolicy.swift in Sources */ = {isa = PBXBuildFile; fileRef = A815AAA32D9108CB00929A9E /* StoreApp11To17_1MigrationPolicy.swift */; };
|
||||
A81A8CB92D68B30B0086C96F /* SingletonGenericMap.swift in Sources */ = {isa = PBXBuildFile; fileRef = A868CFE32D319988002F1201 /* SingletonGenericMap.swift */; };
|
||||
A81A8CBA2D68B3110086C96F /* TreeMap.swift in Sources */ = {isa = PBXBuildFile; fileRef = A81A8CB02D68B0320086C96F /* TreeMap.swift */; };
|
||||
A81A8CBD2D68B43F0086C96F /* LinkedHashMap.swift in Sources */ = {isa = PBXBuildFile; fileRef = A81A8CBC2D68B43F0086C96F /* LinkedHashMap.swift */; };
|
||||
@@ -69,6 +78,8 @@
|
||||
A81A8CD12D68BA9B0086C96F /* TreeMap.swift in Sources */ = {isa = PBXBuildFile; fileRef = A81A8CB02D68B0320086C96F /* TreeMap.swift */; };
|
||||
A81A8CD22D68BAA30086C96F /* SingletonGenericMap.swift in Sources */ = {isa = PBXBuildFile; fileRef = A868CFE32D319988002F1201 /* SingletonGenericMap.swift */; };
|
||||
A81A8CD42D68BAFF0086C96F /* DataStructureTests.xctestplan in Resources */ = {isa = PBXBuildFile; fileRef = A81A8CD32D68BAFF0086C96F /* DataStructureTests.xctestplan */; };
|
||||
A81BF9E52D84CB0C00768940 /* AppPermission17To17_1MigrationPolicy.swift in Sources */ = {isa = PBXBuildFile; fileRef = A81BF9E22D84CB0C00768940 /* AppPermission17To17_1MigrationPolicy.swift */; };
|
||||
A81BF9E72D84CB0C00768940 /* Source17To17_1MigrationPolicy.swift in Sources */ = {isa = PBXBuildFile; fileRef = A81BF9E32D84CB0C00768940 /* Source17To17_1MigrationPolicy.swift */; };
|
||||
A82067842D03DC0600645C0D /* OperatingSystemVersion+Comparable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5708416292448DA00D42D34 /* OperatingSystemVersion+Comparable.swift */; };
|
||||
A82067C42D03E0DE00645C0D /* SemanticVersion in Frameworks */ = {isa = PBXBuildFile; productRef = A82067C32D03E0DE00645C0D /* SemanticVersion */; };
|
||||
A8228B5B2D6E2C0C00F7CE0E /* (null) in Sources */ = {isa = PBXBuildFile; };
|
||||
@@ -77,7 +88,6 @@
|
||||
A859ED5D2D1EE827003DCC58 /* OpenSSL.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = A859ED5B2D1EE80D003DCC58 /* OpenSSL.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||
A86315DF2D3EB2DE0048FA40 /* ErrorProcessing.swift in Sources */ = {isa = PBXBuildFile; fileRef = A86315DE2D3EB2D80048FA40 /* ErrorProcessing.swift */; };
|
||||
A8696EE42D34512C00E96389 /* RemoveAppExtensionsOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8696EE32D34512C00E96389 /* RemoveAppExtensionsOperation.swift */; };
|
||||
A881E7C72D6EF58C00954AD2 /* AltStore11ToAltStore17.xcmappingmodel in Sources */ = {isa = PBXBuildFile; fileRef = A881E7C62D6EF58C00954AD2 /* AltStore11ToAltStore17.xcmappingmodel */; };
|
||||
A881E7CB2D6EF5AB00954AD2 /* StoreApp11To17MigrationPolicy.swift in Sources */ = {isa = PBXBuildFile; fileRef = A881E7CA2D6EF5AB00954AD2 /* StoreApp11To17MigrationPolicy.swift */; };
|
||||
A88B8C492D35AD3200F53F9D /* OperationsLoggingContolView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A88B8C482D35AD3200F53F9D /* OperationsLoggingContolView.swift */; };
|
||||
A88B8C552D35F1EC00F53F9D /* OperationsLoggingControl.swift in Sources */ = {isa = PBXBuildFile; fileRef = A88B8C542D35F1EC00F53F9D /* OperationsLoggingControl.swift */; };
|
||||
@@ -103,6 +113,7 @@
|
||||
A8C6D5142D1EE8D700DF01F1 /* OpenSSL.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = A859ED5B2D1EE80D003DCC58 /* OpenSSL.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||
A8C6D5172D1EE95B00DF01F1 /* OpenSSL.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = A859ED5B2D1EE80D003DCC58 /* OpenSSL.xcframework */; };
|
||||
A8C6D5182D1EE95B00DF01F1 /* OpenSSL.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = A859ED5B2D1EE80D003DCC58 /* OpenSSL.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||
A8C924242D8E73B1009D9953 /* AltStore11ToAltStore17.xcmappingmodel in Sources */ = {isa = PBXBuildFile; fileRef = A8C924232D8E73B1009D9953 /* AltStore11ToAltStore17.xcmappingmodel */; };
|
||||
A8D484D82D0CD306002C691D /* AltBackup.ipa in Resources */ = {isa = PBXBuildFile; fileRef = A8D484D72D0CD306002C691D /* AltBackup.ipa */; };
|
||||
A8D49F532D3D2F9400844B92 /* ProcessInfo+AltStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8D49F522D3D2F9400844B92 /* ProcessInfo+AltStore.swift */; };
|
||||
A8E2DB312D684E2A009E5D31 /* UITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8E2DB2E2D684E2A009E5D31 /* UITests.swift */; };
|
||||
@@ -660,6 +671,15 @@
|
||||
A80D60D12D3D705F00CEF65D /* ReleaseTrack.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReleaseTrack.swift; sourceTree = "<group>"; };
|
||||
A80D790C2D2F20AF00A40F40 /* PaginationIntent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaginationIntent.swift; sourceTree = "<group>"; };
|
||||
A80D790E2D2F217000A40F40 /* PaginationDataHolder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaginationDataHolder.swift; sourceTree = "<group>"; };
|
||||
A815AA942D90D2A100929A9E /* StoreApp17To17_1MigrationPolicy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StoreApp17To17_1MigrationPolicy.swift; sourceTree = "<group>"; };
|
||||
A815AA962D90E16400929A9E /* ReleaseTrack17To17_1MigrationPolicy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReleaseTrack17To17_1MigrationPolicy.swift; sourceTree = "<group>"; };
|
||||
A815AA982D90E5E500929A9E /* AltStore17ToAltStore17_1.xcmappingmodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcmappingmodel; path = AltStore17ToAltStore17_1.xcmappingmodel; sourceTree = "<group>"; };
|
||||
A815AA9E2D9104DD00929A9E /* BuildInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BuildInfo.swift; sourceTree = "<group>"; };
|
||||
A815AAA02D9108BC00929A9E /* AltStore11ToAltStore17_1.xcmappingmodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcmappingmodel; path = AltStore11ToAltStore17_1.xcmappingmodel; sourceTree = "<group>"; };
|
||||
A815AAA22D9108CB00929A9E /* Source11To17_1MigrationPolicy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Source11To17_1MigrationPolicy.swift; sourceTree = "<group>"; };
|
||||
A815AAA32D9108CB00929A9E /* StoreApp11To17_1MigrationPolicy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StoreApp11To17_1MigrationPolicy.swift; sourceTree = "<group>"; };
|
||||
A815AAA42D9108CB00929A9E /* ReleaseTrack11To17_1MigrationPolicy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReleaseTrack11To17_1MigrationPolicy.swift; sourceTree = "<group>"; };
|
||||
A815AAA52D9108CB00929A9E /* AppPermission11To17_1MigrationPolicy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppPermission11To17_1MigrationPolicy.swift; sourceTree = "<group>"; };
|
||||
A81A8CB02D68B0320086C96F /* TreeMap.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TreeMap.swift; sourceTree = "<group>"; };
|
||||
A81A8CB42D68B2180086C96F /* TreeMapTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TreeMapTests.swift; sourceTree = "<group>"; };
|
||||
A81A8CBC2D68B43F0086C96F /* LinkedHashMap.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LinkedHashMap.swift; sourceTree = "<group>"; };
|
||||
@@ -667,6 +687,9 @@
|
||||
A81A8CC52D68BA610086C96F /* DataStructureTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DataStructureTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
A81A8CC72D68BA610086C96F /* DataStructuresTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataStructuresTests.swift; sourceTree = "<group>"; };
|
||||
A81A8CD32D68BAFF0086C96F /* DataStructureTests.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = DataStructureTests.xctestplan; sourceTree = "<group>"; };
|
||||
A81BF9E12D84C9E900768940 /* AltStore 17_1.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "AltStore 17_1.xcdatamodel"; sourceTree = "<group>"; };
|
||||
A81BF9E22D84CB0C00768940 /* AppPermission17To17_1MigrationPolicy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppPermission17To17_1MigrationPolicy.swift; sourceTree = "<group>"; };
|
||||
A81BF9E32D84CB0C00768940 /* Source17To17_1MigrationPolicy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Source17To17_1MigrationPolicy.swift; sourceTree = "<group>"; };
|
||||
A859ED5B2D1EE80D003DCC58 /* OpenSSL.xcframework */ = {isa = PBXFileReference; expectedSignature = "AppleDeveloperProgram:67RAULRX93:Marcin Krzyzanowski"; lastKnownFileType = wrapper.xcframework; name = OpenSSL.xcframework; path = SideStore/AltSign/Dependencies/OpenSSL/Frameworks/OpenSSL.xcframework; sourceTree = "<group>"; };
|
||||
A85ACB8E2D1F31C400AA3DE7 /* AltBackup.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AltBackup.xcconfig; sourceTree = "<group>"; };
|
||||
A85ACB8F2D1F31C400AA3DE7 /* AltStore.debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AltStore.debug.xcconfig; sourceTree = "<group>"; };
|
||||
@@ -679,7 +702,6 @@
|
||||
A86315DE2D3EB2D80048FA40 /* ErrorProcessing.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ErrorProcessing.swift; sourceTree = "<group>"; };
|
||||
A868CFE32D319988002F1201 /* SingletonGenericMap.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SingletonGenericMap.swift; sourceTree = "<group>"; };
|
||||
A8696EE32D34512C00E96389 /* RemoveAppExtensionsOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RemoveAppExtensionsOperation.swift; sourceTree = "<group>"; };
|
||||
A881E7C62D6EF58C00954AD2 /* AltStore11ToAltStore17.xcmappingmodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcmappingmodel; path = AltStore11ToAltStore17.xcmappingmodel; sourceTree = "<group>"; };
|
||||
A881E7CA2D6EF5AB00954AD2 /* StoreApp11To17MigrationPolicy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StoreApp11To17MigrationPolicy.swift; sourceTree = "<group>"; };
|
||||
A881E8562D6FBBAF00954AD2 /* DataStructureTests.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = DataStructureTests.xcconfig; sourceTree = "<group>"; };
|
||||
A88B8C482D35AD3200F53F9D /* OperationsLoggingContolView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OperationsLoggingContolView.swift; sourceTree = "<group>"; };
|
||||
@@ -696,6 +718,7 @@
|
||||
A8C38C2B2D206AD900E83DBD /* AbstractClassError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AbstractClassError.swift; sourceTree = "<group>"; };
|
||||
A8C38C312D206B2500E83DBD /* FileOutputStream.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileOutputStream.swift; sourceTree = "<group>"; };
|
||||
A8C38C372D2084D000E83DBD /* ConsoleLogView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConsoleLogView.swift; sourceTree = "<group>"; };
|
||||
A8C924232D8E73B1009D9953 /* AltStore11ToAltStore17.xcmappingmodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcmappingmodel; path = AltStore11ToAltStore17.xcmappingmodel; sourceTree = "<group>"; };
|
||||
A8D484D72D0CD306002C691D /* AltBackup.ipa */ = {isa = PBXFileReference; lastKnownFileType = file; path = AltBackup.ipa; sourceTree = "<group>"; };
|
||||
A8D49F522D3D2F9400844B92 /* ProcessInfo+AltStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ProcessInfo+AltStore.swift"; sourceTree = "<group>"; };
|
||||
A8E2DB212D684CBD009E5D31 /* UITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = UITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
@@ -1246,6 +1269,17 @@
|
||||
path = Intents;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A815AAA62D9108CB00929A9E /* v11-to-v17_1 */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A815AAA22D9108CB00929A9E /* Source11To17_1MigrationPolicy.swift */,
|
||||
A815AAA32D9108CB00929A9E /* StoreApp11To17_1MigrationPolicy.swift */,
|
||||
A815AAA42D9108CB00929A9E /* ReleaseTrack11To17_1MigrationPolicy.swift */,
|
||||
A815AAA52D9108CB00929A9E /* AppPermission11To17_1MigrationPolicy.swift */,
|
||||
);
|
||||
path = "v11-to-v17_1";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A81A8CB22D68B2030086C96F /* UnitTests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -1281,6 +1315,26 @@
|
||||
path = xcconfigs;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A85E43732D8AF82100E89240 /* v11-to-v17 */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
D5185B812AE1E71D00646E33 /* Source11To17MigrationPolicy.swift */,
|
||||
A881E7CA2D6EF5AB00954AD2 /* StoreApp11To17MigrationPolicy.swift */,
|
||||
);
|
||||
path = "v11-to-v17";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A85E43742D8AF84200E89240 /* v17-to-v17_1 */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A81BF9E32D84CB0C00768940 /* Source17To17_1MigrationPolicy.swift */,
|
||||
A815AA942D90D2A100929A9E /* StoreApp17To17_1MigrationPolicy.swift */,
|
||||
A815AA962D90E16400929A9E /* ReleaseTrack17To17_1MigrationPolicy.swift */,
|
||||
A81BF9E22D84CB0C00768940 /* AppPermission17To17_1MigrationPolicy.swift */,
|
||||
);
|
||||
path = "v17-to-v17_1";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A86315DD2D3EB2BD0048FA40 /* errors */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -1393,6 +1447,7 @@
|
||||
A8C38C272D206AA500E83DBD /* common */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A815AA9E2D9104DD00929A9E /* BuildInfo.swift */,
|
||||
A8B516E52D2668020047047C /* DateTimeUtil.swift */,
|
||||
A8C38C282D206AC100E83DBD /* OutputStream.swift */,
|
||||
A8C38C312D206B2500E83DBD /* FileOutputStream.swift */,
|
||||
@@ -1821,10 +1876,11 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
BF66EEAF2501AECA007EE018 /* InstalledAppPolicy.swift */,
|
||||
D5185B812AE1E71D00646E33 /* Source11To17MigrationPolicy.swift */,
|
||||
BF66EEAE2501AECA007EE018 /* StoreAppPolicy.swift */,
|
||||
D5F99A1928D12B1400476A16 /* StoreApp10ToStoreApp11Policy.swift */,
|
||||
A881E7CA2D6EF5AB00954AD2 /* StoreApp11To17MigrationPolicy.swift */,
|
||||
A85E43732D8AF82100E89240 /* v11-to-v17 */,
|
||||
A85E43742D8AF84200E89240 /* v17-to-v17_1 */,
|
||||
A815AAA62D9108CB00929A9E /* v11-to-v17_1 */,
|
||||
);
|
||||
path = Policies;
|
||||
sourceTree = "<group>";
|
||||
@@ -1832,7 +1888,9 @@
|
||||
BF66EEB02501AECA007EE018 /* Mapping Models */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A881E7C62D6EF58C00954AD2 /* AltStore11ToAltStore17.xcmappingmodel */,
|
||||
A815AAA02D9108BC00929A9E /* AltStore11ToAltStore17_1.xcmappingmodel */,
|
||||
A815AA982D90E5E500929A9E /* AltStore17ToAltStore17_1.xcmappingmodel */,
|
||||
A8C924232D8E73B1009D9953 /* AltStore11ToAltStore17.xcmappingmodel */,
|
||||
D5F99A1728D11DB500476A16 /* AltStore10ToAltStore11.xcmappingmodel */,
|
||||
D5CA0C4D280E249E00469595 /* AltStore9ToAltStore10.xcmappingmodel */,
|
||||
BFBF331A2526762200B7B8C9 /* AltStore8ToAltStore9.xcmappingmodel */,
|
||||
@@ -3098,6 +3156,7 @@
|
||||
A82067842D03DC0600645C0D /* OperatingSystemVersion+Comparable.swift in Sources */,
|
||||
D5FB28EE2ADDF89800A1C337 /* KnownSource.swift in Sources */,
|
||||
BF66EED32501AECA007EE018 /* AltStore2ToAltStore3.xcmappingmodel in Sources */,
|
||||
A815AA972D90E16400929A9E /* ReleaseTrack17To17_1MigrationPolicy.swift in Sources */,
|
||||
BF66EEA52501AEC5007EE018 /* Benefit.swift in Sources */,
|
||||
D52B4ABF2AF183F0005991C3 /* WebViewController.swift in Sources */,
|
||||
BF66EED22501AECA007EE018 /* AltStore4ToAltStore5.xcmappingmodel in Sources */,
|
||||
@@ -3106,17 +3165,26 @@
|
||||
BF66EECD2501AECA007EE018 /* StoreAppPolicy.swift in Sources */,
|
||||
BF66EEE82501AED0007EE018 /* UserDefaults+AltStore.swift in Sources */,
|
||||
BF340E9A250AD39500A192CB /* ViewApp.intentdefinition in Sources */,
|
||||
A8C924242D8E73B1009D9953 /* AltStore11ToAltStore17.xcmappingmodel in Sources */,
|
||||
D552EB062AF453F900A3AB4D /* URL+Normalized.swift in Sources */,
|
||||
BFAECC522501B0A400528F27 /* CodableError.swift in Sources */,
|
||||
A8FD915F2D046F5200322782 /* UserInfoValue.swift in Sources */,
|
||||
D5F9821D2AB900060045751F /* AppScreenshot.swift in Sources */,
|
||||
BF66EE9E2501AEC1007EE018 /* Fetchable.swift in Sources */,
|
||||
BF66EEDF2501AECA007EE018 /* PatreonAccount.swift in Sources */,
|
||||
A815AAA12D9108BC00929A9E /* AltStore11ToAltStore17_1.xcmappingmodel in Sources */,
|
||||
BFAECC532501B0A400528F27 /* ServerProtocol.swift in Sources */,
|
||||
A81BF9E52D84CB0C00768940 /* AppPermission17To17_1MigrationPolicy.swift in Sources */,
|
||||
A81BF9E72D84CB0C00768940 /* Source17To17_1MigrationPolicy.swift in Sources */,
|
||||
BFAECC572501B0A400528F27 /* ConnectionManager.swift in Sources */,
|
||||
BF66EE9D2501AEC1007EE018 /* AppProtocol.swift in Sources */,
|
||||
D519AD46292D665B004B12F9 /* Managed.swift in Sources */,
|
||||
D52A2F972ACB40F700BDF8E3 /* Logger+AltStore.swift in Sources */,
|
||||
A815AA952D90D2A100929A9E /* StoreApp17To17_1MigrationPolicy.swift in Sources */,
|
||||
A815AAA72D9108CB00929A9E /* ReleaseTrack11To17_1MigrationPolicy.swift in Sources */,
|
||||
A815AAA82D9108CB00929A9E /* AppPermission11To17_1MigrationPolicy.swift in Sources */,
|
||||
A815AAA92D9108CB00929A9E /* Source11To17_1MigrationPolicy.swift in Sources */,
|
||||
A815AAAA2D9108CB00929A9E /* StoreApp11To17_1MigrationPolicy.swift in Sources */,
|
||||
BFC712C42512D5F100AB5EBE /* XPCConnection.swift in Sources */,
|
||||
D5CA0C4B280E141900469595 /* ManagedPatron.swift in Sources */,
|
||||
BF66EE8C2501AEB2007EE018 /* Keychain.swift in Sources */,
|
||||
@@ -3179,11 +3247,11 @@
|
||||
BF66EECE2501AECA007EE018 /* InstalledAppPolicy.swift in Sources */,
|
||||
BF1FE359251A9FB000C3CE09 /* NSXPCConnection+MachServices.swift in Sources */,
|
||||
BF66EEA62501AEC5007EE018 /* PatreonAPI.swift in Sources */,
|
||||
A881E7C72D6EF58C00954AD2 /* AltStore11ToAltStore17.xcmappingmodel in Sources */,
|
||||
BF66EED02501AECA007EE018 /* AltStore6ToAltStore7.xcmappingmodel in Sources */,
|
||||
BF66EEDC2501AECA007EE018 /* MergePolicy.swift in Sources */,
|
||||
BF66EEE22501AECA007EE018 /* InstalledExtension.swift in Sources */,
|
||||
BF66EED62501AECA007EE018 /* NewsItem.swift in Sources */,
|
||||
A815AA992D90E5E500929A9E /* AltStore17ToAltStore17_1.xcmappingmodel in Sources */,
|
||||
BF66EEA72501AEC5007EE018 /* Campaign.swift in Sources */,
|
||||
D52C8F032AFC56F000CA0BDD /* StoreCategory.swift in Sources */,
|
||||
BF66EE992501AEBC007EE018 /* ALTSourceUserInfoKey.m in Sources */,
|
||||
@@ -3332,6 +3400,7 @@
|
||||
BF0C4EBD22A1BD8B009A2DD7 /* AppManager.swift in Sources */,
|
||||
BF2901312318F7A800D88A45 /* AppBannerView.swift in Sources */,
|
||||
0EE7FDC42BE8BC7900D1E390 /* ALTLocalizedError.swift in Sources */,
|
||||
A815AA9F2D9104DD00929A9E /* BuildInfo.swift in Sources */,
|
||||
BFF00D342501BDCF00746320 /* IntentHandler.swift in Sources */,
|
||||
BFDBBD80246CB84F004ED2F3 /* RemoveAppBackupOperation.swift in Sources */,
|
||||
A8C38C2A2D206AC100E83DBD /* OutputStream.swift in Sources */,
|
||||
@@ -4340,6 +4409,7 @@
|
||||
BF66EEB72501AECA007EE018 /* AltStore.xcdatamodeld */ = {
|
||||
isa = XCVersionGroup;
|
||||
children = (
|
||||
A81BF9E12D84C9E900768940 /* AltStore 17_1.xcdatamodel */,
|
||||
D51E83802B86926B0092FC61 /* AltStore 17.xcdatamodel */,
|
||||
D52E988928D002D30032BE6B /* AltStore 11.xcdatamodel */,
|
||||
D5CA0C4C280E242500469595 /* AltStore 10.xcdatamodel */,
|
||||
@@ -4353,7 +4423,7 @@
|
||||
BF66EEBD2501AECA007EE018 /* AltStore 2.xcdatamodel */,
|
||||
BF66EEB92501AECA007EE018 /* AltStore.xcdatamodel */,
|
||||
);
|
||||
currentVersion = D51E83802B86926B0092FC61 /* AltStore 17.xcdatamodel */;
|
||||
currentVersion = A81BF9E12D84C9E900768940 /* AltStore 17_1.xcdatamodel */;
|
||||
path = AltStore.xcdatamodeld;
|
||||
sourceTree = "<group>";
|
||||
versionGroupType = wrapper.xcdatamodel;
|
||||
|
||||
@@ -11,6 +11,7 @@ import CoreData
|
||||
|
||||
import AltStoreCore
|
||||
import Roxas
|
||||
import SemanticVersion
|
||||
|
||||
@objc(FetchSourceOperation)
|
||||
final class FetchSourceOperation: ResultOperation<Source>
|
||||
@@ -246,9 +247,20 @@ private extension FetchSourceOperation
|
||||
#endif
|
||||
}
|
||||
|
||||
if let previousSourceID = self.$source.identifier
|
||||
let incomingSourceID = source.identifier
|
||||
if let previousSourceID = self.$source.identifier,
|
||||
incomingSourceID != previousSourceID
|
||||
{
|
||||
guard source.identifier == previousSourceID else { throw SourceError.changedID(source.identifier, previousID: previousSourceID, source: source) }
|
||||
// if let version = BuildInfo().marketing_version,
|
||||
// SemanticVersion(version)! <= SemanticVersion("0.6.1")!
|
||||
// {
|
||||
// // delete the source, so that incoming will be saved.
|
||||
// self.source?.managedObjectContext?.delete(self.source!)
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
throw SourceError.changedID(source.identifier, previousID: self.$source.identifier ?? "nil", source: source)
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -263,50 +263,6 @@ final class SettingsViewController: UITableViewController
|
||||
|
||||
}
|
||||
|
||||
private class BuildInfo{
|
||||
private static let MARKETING_VERSION_TAG = "CFBundleShortVersionString"
|
||||
private static let CURRENT_PROJECT_VERSION_TAG = kCFBundleVersionKey as String
|
||||
|
||||
private static let XCODE_VERSION_TAG = "DTXcode"
|
||||
private static let XCODE_REVISION_TAG = "DTXcodeBuild"
|
||||
|
||||
let bundle: Bundle
|
||||
|
||||
public init(){
|
||||
bundle = Bundle.main
|
||||
}
|
||||
|
||||
enum BundleError: Swift.Error {
|
||||
case invalidURL
|
||||
}
|
||||
|
||||
public init(url: URL) throws {
|
||||
guard let bundle = Bundle(url: url) else {
|
||||
throw BundleError.invalidURL
|
||||
}
|
||||
self.bundle = bundle
|
||||
}
|
||||
|
||||
public lazy var project_version: String? = {
|
||||
let version = bundle.object(forInfoDictionaryKey: Self.CURRENT_PROJECT_VERSION_TAG) as? String
|
||||
return version
|
||||
}()
|
||||
|
||||
public lazy var marketing_version: String? = {
|
||||
let version = bundle.object(forInfoDictionaryKey: Self.MARKETING_VERSION_TAG) as? String
|
||||
return version
|
||||
}()
|
||||
|
||||
public lazy var xcode: String? = {
|
||||
let xcode = bundle.object(forInfoDictionaryKey: Self.XCODE_VERSION_TAG) as? String
|
||||
return xcode
|
||||
}()
|
||||
|
||||
public lazy var xcode_revision: String? = {
|
||||
let revision = bundle.object(forInfoDictionaryKey: Self.XCODE_REVISION_TAG) as? String
|
||||
return revision
|
||||
}()
|
||||
}
|
||||
|
||||
private extension SettingsViewController
|
||||
{
|
||||
|
||||
@@ -514,27 +514,27 @@ extension SourcesViewController: NSFetchedResultsControllerDelegate
|
||||
let context = DatabaseManager.shared.persistentContainer.newBackgroundContext()
|
||||
context.performAndWait {
|
||||
_ = Source.make(name: "OatmealDome's AltStore Source",
|
||||
identifier: "me.oatmealdome.altstore",
|
||||
groupID: "me.oatmealdome.altstore",
|
||||
sourceURL: URL(string: "https://altstore.oatmealdome.me")!,
|
||||
context: context)
|
||||
|
||||
_ = Source.make(name: "UTM Repository",
|
||||
identifier: "com.utmapp.repos.UTM",
|
||||
groupID: "com.utmapp.repos.UTM",
|
||||
sourceURL: URL(string: "https://alt.getutm.app")!,
|
||||
context: context)
|
||||
|
||||
_ = Source.make(name: "Flyinghead",
|
||||
identifier: "com.flyinghead.source",
|
||||
groupID: "com.flyinghead.source",
|
||||
sourceURL: URL(string: "https://flyinghead.github.io/flycast-builds/altstore.json")!,
|
||||
context: context)
|
||||
|
||||
_ = Source.make(name: "Provenance",
|
||||
identifier: "org.provenance-emu.AltStore",
|
||||
groupID: "org.provenance-emu.AltStore",
|
||||
sourceURL: URL(string: "https://provenance-emu.com/apps.json")!,
|
||||
context: context)
|
||||
|
||||
_ = Source.make(name: "PojavLauncher Repository",
|
||||
identifier: "dev.crystall1ne.repos.PojavLauncher",
|
||||
groupID: "dev.crystall1ne.repos.PojavLauncher",
|
||||
sourceURL: URL(string: "http://alt.crystall1ne.dev")!,
|
||||
context: context)
|
||||
|
||||
|
||||
@@ -3,6 +3,6 @@
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>_XCCurrentVersionName</key>
|
||||
<string>AltStore 17.xcdatamodel</string>
|
||||
<string>AltStore 17_1.xcdatamodel</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
@@ -0,0 +1,315 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="23605" systemVersion="24D70" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier="v17.1">
|
||||
<entity name="Account" representedClassName="Account" syncable="YES">
|
||||
<attribute name="appleID" attributeType="String"/>
|
||||
<attribute name="firstName" attributeType="String"/>
|
||||
<attribute name="identifier" attributeType="String"/>
|
||||
<attribute name="isActiveAccount" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="lastName" attributeType="String"/>
|
||||
<relationship name="teams" toMany="YES" deletionRule="Cascade" destinationEntity="Team" inverseName="account" inverseEntity="Team"/>
|
||||
<uniquenessConstraints>
|
||||
<uniquenessConstraint>
|
||||
<constraint value="identifier"/>
|
||||
</uniquenessConstraint>
|
||||
</uniquenessConstraints>
|
||||
</entity>
|
||||
<entity name="AppID" representedClassName="AppID" syncable="YES">
|
||||
<attribute name="bundleIdentifier" attributeType="String"/>
|
||||
<attribute name="expirationDate" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
|
||||
<attribute name="features" attributeType="Transformable" valueTransformerName="ALTSecureValueTransformer"/>
|
||||
<attribute name="identifier" attributeType="String"/>
|
||||
<attribute name="name" attributeType="String"/>
|
||||
<relationship name="team" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="Team" inverseName="appIDs" inverseEntity="Team"/>
|
||||
<uniquenessConstraints>
|
||||
<uniquenessConstraint>
|
||||
<constraint value="identifier"/>
|
||||
</uniquenessConstraint>
|
||||
</uniquenessConstraints>
|
||||
</entity>
|
||||
<entity name="AppPermission" representedClassName="AppPermission" syncable="YES">
|
||||
<attribute name="appBundleID" optional="YES" attributeType="String"/>
|
||||
<attribute name="permission" optional="YES" attributeType="String"/>
|
||||
<attribute name="sourceID" optional="YES" attributeType="String"/>
|
||||
<attribute name="type" attributeType="String"/>
|
||||
<attribute name="usageDescription" attributeType="String"/>
|
||||
<relationship name="app" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="StoreApp" inverseName="permissions" inverseEntity="StoreApp"/>
|
||||
<uniquenessConstraints>
|
||||
<uniquenessConstraint>
|
||||
<constraint value="sourceID"/>
|
||||
<constraint value="appBundleID"/>
|
||||
<constraint value="type"/>
|
||||
<constraint value="permission"/>
|
||||
</uniquenessConstraint>
|
||||
</uniquenessConstraints>
|
||||
</entity>
|
||||
<entity name="AppScreenshot" representedClassName="AppScreenshot" syncable="YES">
|
||||
<attribute name="appBundleID" optional="YES" attributeType="String"/>
|
||||
<attribute name="deviceType" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="height" optional="YES" attributeType="Integer 16" usesScalarValueType="NO"/>
|
||||
<attribute name="imageURL" attributeType="URI"/>
|
||||
<attribute name="sourceID" optional="YES" attributeType="String"/>
|
||||
<attribute name="width" optional="YES" attributeType="Integer 16" usesScalarValueType="NO"/>
|
||||
<relationship name="app" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="StoreApp" inverseName="screenshots" inverseEntity="StoreApp"/>
|
||||
<uniquenessConstraints>
|
||||
<uniquenessConstraint>
|
||||
<constraint value="sourceID"/>
|
||||
<constraint value="appBundleID"/>
|
||||
<constraint value="imageURL"/>
|
||||
</uniquenessConstraint>
|
||||
</uniquenessConstraints>
|
||||
</entity>
|
||||
<entity name="AppVersion" representedClassName="AppVersion" syncable="YES">
|
||||
<attribute name="appBundleID" optional="YES" attributeType="String"/>
|
||||
<attribute name="buildVersion" optional="YES" attributeType="String"/>
|
||||
<attribute name="channel" optional="YES" attributeType="String"/>
|
||||
<attribute name="date" attributeType="Date" usesScalarValueType="NO"/>
|
||||
<attribute name="downloadURL" attributeType="URI"/>
|
||||
<attribute name="localizedDescription" optional="YES" attributeType="String"/>
|
||||
<attribute name="maxOSVersion" optional="YES" attributeType="String"/>
|
||||
<attribute name="minOSVersion" optional="YES" attributeType="String"/>
|
||||
<attribute name="sha256" optional="YES" attributeType="String"/>
|
||||
<attribute name="size" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="sourceID" optional="YES" attributeType="String"/>
|
||||
<attribute name="version" attributeType="String"/>
|
||||
<relationship name="app" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="StoreApp" inverseName="versions" inverseEntity="StoreApp"/>
|
||||
<relationship name="latestVersionApp" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="StoreApp" inverseName="latestVersion" inverseEntity="StoreApp"/>
|
||||
<relationship name="releaseTrack" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="ReleaseTrack" inverseName="releases" inverseEntity="ReleaseTrack"/>
|
||||
<uniquenessConstraints>
|
||||
<uniquenessConstraint>
|
||||
<constraint value="sourceID"/>
|
||||
<constraint value="appBundleID"/>
|
||||
<constraint value="version"/>
|
||||
<constraint value="buildVersion"/>
|
||||
</uniquenessConstraint>
|
||||
</uniquenessConstraints>
|
||||
</entity>
|
||||
<entity name="InstalledApp" representedClassName="InstalledApp" syncable="YES">
|
||||
<attribute name="buildVersion" optional="YES" attributeType="String"/>
|
||||
<attribute name="bundleIdentifier" attributeType="String"/>
|
||||
<attribute name="certificateSerialNumber" optional="YES" attributeType="String"/>
|
||||
<attribute name="expirationDate" attributeType="Date" usesScalarValueType="NO"/>
|
||||
<attribute name="hasAlternateIcon" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="hasUpdate" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="installedDate" attributeType="Date" usesScalarValueType="NO"/>
|
||||
<attribute name="isActive" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES"/>
|
||||
<attribute name="isRefreshing" transient="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="name" attributeType="String"/>
|
||||
<attribute name="needsResign" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="refreshedDate" attributeType="Date" usesScalarValueType="NO"/>
|
||||
<attribute name="resignedBundleIdentifier" attributeType="String"/>
|
||||
<attribute name="storeBuildVersion" optional="YES" attributeType="String"/>
|
||||
<attribute name="version" attributeType="String"/>
|
||||
<relationship name="appExtensions" toMany="YES" deletionRule="Cascade" destinationEntity="InstalledExtension" inverseName="parentApp" inverseEntity="InstalledExtension"/>
|
||||
<relationship name="loggedErrors" toMany="YES" deletionRule="Nullify" destinationEntity="LoggedError" inverseName="installedApp" inverseEntity="LoggedError"/>
|
||||
<relationship name="storeApp" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="StoreApp" inverseName="installedApp" inverseEntity="StoreApp"/>
|
||||
<relationship name="team" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="Team" inverseName="installedApps" inverseEntity="Team"/>
|
||||
<uniquenessConstraints>
|
||||
<uniquenessConstraint>
|
||||
<constraint value="bundleIdentifier"/>
|
||||
</uniquenessConstraint>
|
||||
</uniquenessConstraints>
|
||||
</entity>
|
||||
<entity name="InstalledExtension" representedClassName="InstalledExtension" syncable="YES">
|
||||
<attribute name="bundleIdentifier" attributeType="String"/>
|
||||
<attribute name="expirationDate" attributeType="Date" usesScalarValueType="NO"/>
|
||||
<attribute name="installedDate" attributeType="Date" usesScalarValueType="NO"/>
|
||||
<attribute name="name" attributeType="String"/>
|
||||
<attribute name="refreshedDate" attributeType="Date" usesScalarValueType="NO"/>
|
||||
<attribute name="resignedBundleIdentifier" attributeType="String"/>
|
||||
<attribute name="version" attributeType="String"/>
|
||||
<relationship name="parentApp" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="InstalledApp" inverseName="appExtensions" inverseEntity="InstalledApp"/>
|
||||
</entity>
|
||||
<entity name="LoggedError" representedClassName="LoggedError" syncable="YES">
|
||||
<attribute name="appBundleID" attributeType="String"/>
|
||||
<attribute name="appName" attributeType="String"/>
|
||||
<attribute name="code" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="date" attributeType="Date" usesScalarValueType="NO"/>
|
||||
<attribute name="domain" attributeType="String"/>
|
||||
<attribute name="operation" optional="YES" attributeType="String"/>
|
||||
<attribute name="userInfo" attributeType="Transformable" valueTransformerName="ALTSecureValueTransformer"/>
|
||||
<relationship name="installedApp" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="InstalledApp" inverseName="loggedErrors" inverseEntity="InstalledApp"/>
|
||||
<relationship name="storeApp" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="StoreApp" inverseName="loggedErrors" inverseEntity="StoreApp"/>
|
||||
</entity>
|
||||
<entity name="NewsItem" representedClassName="NewsItem" syncable="YES">
|
||||
<attribute name="appID" optional="YES" attributeType="String"/>
|
||||
<attribute name="caption" attributeType="String"/>
|
||||
<attribute name="date" attributeType="Date" usesScalarValueType="NO"/>
|
||||
<attribute name="externalURL" optional="YES" attributeType="URI"/>
|
||||
<attribute name="identifier" attributeType="String"/>
|
||||
<attribute name="imageURL" optional="YES" attributeType="URI"/>
|
||||
<attribute name="isSilent" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES"/>
|
||||
<attribute name="sortIndex" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="sourceIdentifier" optional="YES" attributeType="String"/>
|
||||
<attribute name="tintColor" optional="YES" attributeType="Transformable" valueTransformerName="ALTSecureValueTransformer"/>
|
||||
<attribute name="title" attributeType="String"/>
|
||||
<relationship name="source" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="Source" inverseName="newsItems" inverseEntity="Source"/>
|
||||
<relationship name="storeApp" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="StoreApp" inverseName="newsItems" inverseEntity="StoreApp"/>
|
||||
<uniquenessConstraints>
|
||||
<uniquenessConstraint>
|
||||
<constraint value="identifier"/>
|
||||
<constraint value="sourceIdentifier"/>
|
||||
</uniquenessConstraint>
|
||||
</uniquenessConstraints>
|
||||
</entity>
|
||||
<entity name="PatreonAccount" representedClassName="PatreonAccount" syncable="YES">
|
||||
<attribute name="firstName" optional="YES" attributeType="String"/>
|
||||
<attribute name="identifier" attributeType="String"/>
|
||||
<attribute name="isPatron" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="name" attributeType="String"/>
|
||||
<relationship name="pledges" toMany="YES" deletionRule="Cascade" destinationEntity="Pledge" inverseName="account" inverseEntity="Pledge"/>
|
||||
<uniquenessConstraints>
|
||||
<uniquenessConstraint>
|
||||
<constraint value="identifier"/>
|
||||
</uniquenessConstraint>
|
||||
</uniquenessConstraints>
|
||||
</entity>
|
||||
<entity name="Patron" representedClassName="ManagedPatron" syncable="YES">
|
||||
<attribute name="identifier" attributeType="String"/>
|
||||
<attribute name="name" attributeType="String"/>
|
||||
<uniquenessConstraints>
|
||||
<uniquenessConstraint>
|
||||
<constraint value="identifier"/>
|
||||
</uniquenessConstraint>
|
||||
</uniquenessConstraints>
|
||||
</entity>
|
||||
<entity name="Pledge" representedClassName="Pledge" syncable="YES">
|
||||
<attribute name="amount" attributeType="Decimal" defaultValueString="0"/>
|
||||
<attribute name="campaignURL" attributeType="URI"/>
|
||||
<attribute name="identifier" attributeType="String"/>
|
||||
<relationship name="account" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="PatreonAccount" inverseName="pledges" inverseEntity="PatreonAccount"/>
|
||||
<relationship name="rewards" optional="YES" toMany="YES" deletionRule="Cascade" destinationEntity="PledgeReward" inverseName="pledge" inverseEntity="PledgeReward"/>
|
||||
<relationship name="tiers" optional="YES" toMany="YES" deletionRule="Cascade" destinationEntity="PledgeTier" inverseName="pledge" inverseEntity="PledgeTier"/>
|
||||
<uniquenessConstraints>
|
||||
<uniquenessConstraint>
|
||||
<constraint value="identifier"/>
|
||||
</uniquenessConstraint>
|
||||
</uniquenessConstraints>
|
||||
</entity>
|
||||
<entity name="PledgeReward" representedClassName="PledgeReward" syncable="YES">
|
||||
<attribute name="identifier" attributeType="String"/>
|
||||
<attribute name="name" attributeType="String"/>
|
||||
<relationship name="pledge" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="Pledge" inverseName="rewards" inverseEntity="Pledge"/>
|
||||
<uniquenessConstraints>
|
||||
<uniquenessConstraint>
|
||||
<constraint value="identifier"/>
|
||||
</uniquenessConstraint>
|
||||
</uniquenessConstraints>
|
||||
</entity>
|
||||
<entity name="PledgeTier" representedClassName="PledgeTier" syncable="YES">
|
||||
<attribute name="amount" attributeType="Decimal" defaultValueString="0.0"/>
|
||||
<attribute name="identifier" attributeType="String"/>
|
||||
<attribute name="name" optional="YES" attributeType="String"/>
|
||||
<relationship name="pledge" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="Pledge" inverseName="tiers" inverseEntity="Pledge"/>
|
||||
<uniquenessConstraints>
|
||||
<uniquenessConstraint>
|
||||
<constraint value="identifier"/>
|
||||
</uniquenessConstraint>
|
||||
</uniquenessConstraints>
|
||||
</entity>
|
||||
<entity name="RefreshAttempt" representedClassName="RefreshAttempt" syncable="YES">
|
||||
<attribute name="date" attributeType="Date" usesScalarValueType="NO"/>
|
||||
<attribute name="errorDescription" optional="YES" attributeType="String"/>
|
||||
<attribute name="identifier" attributeType="String"/>
|
||||
<attribute name="isSuccess" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES"/>
|
||||
<uniquenessConstraints>
|
||||
<uniquenessConstraint>
|
||||
<constraint value="identifier"/>
|
||||
</uniquenessConstraint>
|
||||
</uniquenessConstraints>
|
||||
</entity>
|
||||
<entity name="ReleaseTrack" representedClassName="ReleaseTrack" syncable="YES">
|
||||
<attribute name="appBundleID" optional="YES" attributeType="String"/>
|
||||
<attribute name="sourceID" optional="YES" attributeType="String"/>
|
||||
<attribute name="track" attributeType="String"/>
|
||||
<relationship name="releases" optional="YES" toMany="YES" deletionRule="Cascade" ordered="YES" destinationEntity="AppVersion" inverseName="releaseTrack" inverseEntity="AppVersion"/>
|
||||
<relationship name="storeApp" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="StoreApp" inverseName="releaseTracks" inverseEntity="StoreApp"/>
|
||||
<uniquenessConstraints>
|
||||
<uniquenessConstraint>
|
||||
<constraint value="sourceID"/>
|
||||
<constraint value="appBundleID"/>
|
||||
<constraint value="track"/>
|
||||
</uniquenessConstraint>
|
||||
</uniquenessConstraints>
|
||||
</entity>
|
||||
<entity name="Source" representedClassName="Source" syncable="YES">
|
||||
<attribute name="error" optional="YES" attributeType="Transformable" valueTransformerName="ALTSecureValueTransformer"/>
|
||||
<attribute name="featuredSortID" optional="YES" attributeType="String"/>
|
||||
<attribute name="groupID" optional="YES" attributeType="String"/>
|
||||
<attribute name="hasFeaturedApps" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="headerImageURL" optional="YES" attributeType="URI"/>
|
||||
<attribute name="iconURL" optional="YES" attributeType="URI"/>
|
||||
<attribute name="identifier" attributeType="String"/>
|
||||
<attribute name="localizedDescription" optional="YES" attributeType="String"/>
|
||||
<attribute name="name" attributeType="String"/>
|
||||
<attribute name="patreonURL" optional="YES" attributeType="URI"/>
|
||||
<attribute name="sourceURL" attributeType="URI"/>
|
||||
<attribute name="subtitle" optional="YES" attributeType="String"/>
|
||||
<attribute name="tintColor" optional="YES" attributeType="Transformable" valueTransformerName="ALTSecureValueTransformer"/>
|
||||
<attribute name="version" attributeType="Integer 64" defaultValueString="1" usesScalarValueType="YES"/>
|
||||
<attribute name="websiteURL" optional="YES" attributeType="URI"/>
|
||||
<relationship name="apps" toMany="YES" deletionRule="Cascade" ordered="YES" destinationEntity="StoreApp" inverseName="source" inverseEntity="StoreApp"/>
|
||||
<relationship name="featuredApps" optional="YES" toMany="YES" deletionRule="Nullify" ordered="YES" destinationEntity="StoreApp" inverseName="featuringSource" inverseEntity="StoreApp"/>
|
||||
<relationship name="newsItems" toMany="YES" deletionRule="Cascade" ordered="YES" destinationEntity="NewsItem" inverseName="source" inverseEntity="NewsItem"/>
|
||||
<uniquenessConstraints>
|
||||
<uniquenessConstraint>
|
||||
<constraint value="identifier"/>
|
||||
</uniquenessConstraint>
|
||||
</uniquenessConstraints>
|
||||
</entity>
|
||||
<entity name="StoreApp" representedClassName="StoreApp" syncable="YES">
|
||||
<attribute name="bundleIdentifier" attributeType="String"/>
|
||||
<attribute name="category" optional="YES" attributeType="String"/>
|
||||
<attribute name="developerName" attributeType="String"/>
|
||||
<attribute name="downloadURL" optional="YES" attributeType="URI"/>
|
||||
<attribute name="featuredSortID" optional="YES" attributeType="String"/>
|
||||
<attribute name="iconURL" attributeType="URI"/>
|
||||
<attribute name="isHiddenWithoutPledge" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="isPledged" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="isPledgeRequired" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="localizedDescription" attributeType="String"/>
|
||||
<attribute name="marketplaceID" optional="YES" attributeType="String"/>
|
||||
<attribute name="name" attributeType="String"/>
|
||||
<attribute name="pledgeAmount" optional="YES" attributeType="Decimal"/>
|
||||
<attribute name="pledgeCurrency" optional="YES" attributeType="String"/>
|
||||
<attribute name="prefersCustomPledge" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="screenshotURLs" attributeType="Transformable" valueTransformerName="ALTSecureValueTransformer"/>
|
||||
<attribute name="size" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="sortIndex" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="sourceIdentifier" optional="YES" attributeType="String"/>
|
||||
<attribute name="subtitle" optional="YES" attributeType="String"/>
|
||||
<attribute name="tintColor" optional="YES" attributeType="Transformable" valueTransformerName="ALTSecureValueTransformer"/>
|
||||
<attribute name="version" optional="YES" attributeType="String"/>
|
||||
<attribute name="versionDate" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
|
||||
<attribute name="versionDescription" optional="YES" attributeType="String"/>
|
||||
<relationship name="featuringSource" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="Source" inverseName="featuredApps" inverseEntity="Source"/>
|
||||
<relationship name="installedApp" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="InstalledApp" inverseName="storeApp" inverseEntity="InstalledApp"/>
|
||||
<relationship name="latestVersion" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="AppVersion" inverseName="latestVersionApp" inverseEntity="AppVersion"/>
|
||||
<relationship name="loggedErrors" toMany="YES" deletionRule="Nullify" destinationEntity="LoggedError" inverseName="storeApp" inverseEntity="LoggedError"/>
|
||||
<relationship name="newsItems" toMany="YES" deletionRule="Nullify" destinationEntity="NewsItem" inverseName="storeApp" inverseEntity="NewsItem"/>
|
||||
<relationship name="permissions" toMany="YES" deletionRule="Cascade" destinationEntity="AppPermission" inverseName="app" inverseEntity="AppPermission"/>
|
||||
<relationship name="releaseTracks" optional="YES" toMany="YES" deletionRule="Cascade" ordered="YES" destinationEntity="ReleaseTrack" inverseName="storeApp" inverseEntity="ReleaseTrack"/>
|
||||
<relationship name="screenshots" toMany="YES" deletionRule="Cascade" ordered="YES" destinationEntity="AppScreenshot" inverseName="app" inverseEntity="AppScreenshot"/>
|
||||
<relationship name="source" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="Source" inverseName="apps" inverseEntity="Source"/>
|
||||
<relationship name="versions" toMany="YES" deletionRule="Cascade" ordered="YES" destinationEntity="AppVersion" inverseName="app" inverseEntity="AppVersion"/>
|
||||
<uniquenessConstraints>
|
||||
<uniquenessConstraint>
|
||||
<constraint value="sourceIdentifier"/>
|
||||
<constraint value="bundleIdentifier"/>
|
||||
</uniquenessConstraint>
|
||||
</uniquenessConstraints>
|
||||
</entity>
|
||||
<entity name="Team" representedClassName="Team" syncable="YES">
|
||||
<attribute name="identifier" attributeType="String"/>
|
||||
<attribute name="isActiveTeam" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="name" attributeType="String"/>
|
||||
<attribute name="type" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<relationship name="account" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="Account" inverseName="teams" inverseEntity="Account"/>
|
||||
<relationship name="appIDs" toMany="YES" deletionRule="Cascade" destinationEntity="AppID" inverseName="team" inverseEntity="AppID"/>
|
||||
<relationship name="installedApps" toMany="YES" deletionRule="Nullify" destinationEntity="InstalledApp" inverseName="team" inverseEntity="InstalledApp"/>
|
||||
<uniquenessConstraints>
|
||||
<uniquenessConstraint>
|
||||
<constraint value="identifier"/>
|
||||
</uniquenessConstraint>
|
||||
</uniquenessConstraints>
|
||||
</entity>
|
||||
</model>
|
||||
@@ -33,7 +33,7 @@ public class AppPermission: BaseEntity
|
||||
default: return UnknownAppPermission(rawValue: self._permission)
|
||||
}
|
||||
}
|
||||
@NSManaged @objc(permission) private var _permission: String
|
||||
@NSManaged @objc(permission) private(set) public var _permission: String
|
||||
|
||||
// Set by StoreApp.
|
||||
@NSManaged public var appBundleID: String
|
||||
|
||||
@@ -213,6 +213,7 @@ extension MergePolicy{
|
||||
}
|
||||
|
||||
default:
|
||||
// break
|
||||
// Unknown context-level conflict.
|
||||
// assertionFailure("MergePolicy is only intended to work with database-level conflicts.")
|
||||
assertionFailure("Context Conflict Detected: is there ambigious data in your incoming sources?\nConflict:\(conflict)")
|
||||
|
||||
@@ -505,13 +505,14 @@ cxIAAYagXxAPTlNLZXllZEFyY2hpdmVy0QAIAAlUcm9vdIABrxESLAALAAwAGQA1ADYANwBjAGQAZQBm
|
||||
<relationship name="relationshipmappings" type="0/0" destination="XDDEVRELATIONSHIPMAPPING" idrefs="z142 z119 z223 z116 z229 z139 z236 z136 z214 z216"></relationship>
|
||||
</object>
|
||||
<object type="XDDEVENTITYMAPPING" id="z198">
|
||||
<attribute name="migrationpolicyclassname" type="string"></attribute>
|
||||
<attribute name="sourcename" type="string">AppPermission</attribute>
|
||||
<attribute name="mappingtypename" type="string">Undefined</attribute>
|
||||
<attribute name="mappingnumber" type="int16">17</attribute>
|
||||
<attribute name="destinationname" type="string">AppPermission</attribute>
|
||||
<attribute name="autogenerateexpression" type="bool">1</attribute>
|
||||
<relationship name="mappingmodel" type="1/1" destination="XDDEVMAPPINGMODEL" idrefs="z192"></relationship>
|
||||
<relationship name="attributemappings" type="0/0" destination="XDDEVATTRIBUTEMAPPING" idrefs="z213 z240 z191 z123 z287"></relationship>
|
||||
<relationship name="attributemappings" type="0/0" destination="XDDEVATTRIBUTEMAPPING" idrefs="z123 z213 z287 z240 z191"></relationship>
|
||||
<relationship name="relationshipmappings" type="0/0" destination="XDDEVRELATIONSHIPMAPPING" idrefs="z288"></relationship>
|
||||
</object>
|
||||
<object type="XDDEVENTITYMAPPING" id="z199">
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// SourceMigrationPolicy.swift
|
||||
// Source11To17MigrationPolicy.swift
|
||||
// AltStoreCore
|
||||
//
|
||||
// Created by Riley Testut on 10/19/23.
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// StoreAppMigration11To17Policy.swift
|
||||
// StoreApp11To17MigrationPolicy.swift
|
||||
// AltStore
|
||||
//
|
||||
// Created by Magesh K on 25/02/25.
|
||||
@@ -108,7 +108,7 @@ class StoreApp11To17MigrationPolicy: NSEntityMigrationPolicy {
|
||||
|
||||
// Create a new ReleaseTrack entity
|
||||
let context = dInstance.managedObjectContext!
|
||||
let releaseTrack = NSEntityDescription.insertNewObject(forEntityName: ReleaseTrack.entity().name!, into: context)
|
||||
let releaseTrack = NSEntityDescription.insertNewObject(forEntityName: ReleaseTrack.entity().name ?? ReleaseTrack.description(), into: context)
|
||||
releaseTrack.setValue(defaultChannel, forKey: #keyPath(ReleaseTrack._track))
|
||||
|
||||
// Connect the releaseTrack to the destination StoreApp
|
||||
@@ -116,7 +116,7 @@ class StoreApp11To17MigrationPolicy: NSEntityMigrationPolicy {
|
||||
|
||||
|
||||
// Find the mapping name for AppVersion (make sure this exactly matches your mapping model)
|
||||
let appVersionMappingName = findEntityMappingName(for: AppVersion.entity().name!, in: manager)
|
||||
let appVersionMappingName = findEntityMappingName(for: AppVersion.entity().name ?? AppVersion.description(), in: manager)
|
||||
|
||||
// Create a mutable ordered set for the destination AppVersion objects
|
||||
let destinationVersionsSet = NSMutableOrderedSet()
|
||||
@@ -145,5 +145,5 @@ class StoreApp11To17MigrationPolicy: NSEntityMigrationPolicy {
|
||||
// dInstance.setValue(NSOrderedSet(), forKey: #keyPath(StoreApp._versions))
|
||||
dInstance.setValue(nil, forKey: #keyPath(StoreApp._versions))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
//
|
||||
// AppPermission17to17_1MigrationPolicy.swift
|
||||
// AltStore
|
||||
//
|
||||
// Created by Magesh K on 15/03/25.
|
||||
// Copyright © 2025 SideStore. All rights reserved.
|
||||
//
|
||||
|
||||
import CoreData
|
||||
|
||||
@objc(AppPermission11To17_1MigrationPolicy)
|
||||
class AppPermission11To17_1MigrationPolicy: AppPermission17To17_1MigrationPolicy {
|
||||
|
||||
override func createDestinationInstances(forSource sInstance: NSManagedObject, in mapping: NSEntityMapping, manager: NSMigrationManager) throws {
|
||||
// Let the default implementation create the basic destination AppPermission
|
||||
try super.createDestinationInstances(forSource: sInstance, in: mapping, manager: manager)
|
||||
}
|
||||
|
||||
|
||||
|
||||
override func createRelationships(
|
||||
forDestination dInstance: NSManagedObject,
|
||||
in mapping: NSEntityMapping,
|
||||
manager: NSMigrationManager
|
||||
) throws {
|
||||
try super.createRelationships(forDestination: dInstance, in: mapping, manager: manager)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
//
|
||||
// ReleaseTrack11To17_1MigrationPolicy.swift
|
||||
// AltStore
|
||||
//
|
||||
// Created by Magesh K on 15/03/25.
|
||||
// Copyright © 2025 SideStore. All rights reserved.
|
||||
//
|
||||
|
||||
import CoreData
|
||||
|
||||
@objc(ReleaseTrack11To17_1MigrationPolicy)
|
||||
class ReleaseTrack11To17_1MigrationPolicy: ReleaseTrack17To17_1MigrationPolicy {
|
||||
|
||||
override func createDestinationInstances(forSource sInstance: NSManagedObject, in mapping: NSEntityMapping, manager: NSMigrationManager) throws {
|
||||
try super.createDestinationInstances(forSource: sInstance, in: mapping, manager: manager)
|
||||
}
|
||||
|
||||
|
||||
override func createRelationships(
|
||||
forDestination dInstance: NSManagedObject,
|
||||
in mapping: NSEntityMapping,
|
||||
manager: NSMigrationManager
|
||||
) throws {
|
||||
try super.createRelationships(forDestination: dInstance, in: mapping, manager: manager)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
//
|
||||
// Source11To17_1MigrationPolicy.swift
|
||||
// AltStore
|
||||
//
|
||||
// Created by Magesh K on 15/03/25.
|
||||
// Copyright © 2025 SideStore. All rights reserved.
|
||||
//
|
||||
|
||||
import CoreData
|
||||
|
||||
@objc(Source11To17_1MigrationPolicy)
|
||||
class Source11To17_1MigrationPolicy: Source17To17_1MigrationPolicy
|
||||
{
|
||||
override func createDestinationInstances(forSource sInstance: NSManagedObject, in mapping: NSEntityMapping, manager: NSMigrationManager) throws {
|
||||
// Let the default implementation create the basic destination AppPermission
|
||||
try super.createDestinationInstances(forSource: sInstance, in: mapping, manager: manager)
|
||||
}
|
||||
|
||||
override func createRelationships(forDestination dInstance: NSManagedObject, in mapping: NSEntityMapping, manager: NSMigrationManager) throws
|
||||
{
|
||||
try super.createRelationships(forDestination: dInstance, in: mapping, manager: manager)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
//
|
||||
// StoreApp11To17_1MigrationPolicy.swift
|
||||
// AltStore
|
||||
//
|
||||
// Created by Magesh K on 15/03/25.
|
||||
// Copyright © 2025 SideStore. All rights reserved.
|
||||
//
|
||||
|
||||
import CoreData
|
||||
|
||||
fileprivate extension NSManagedObject
|
||||
{
|
||||
var storeAppReleaseTracks: NSOrderedSet? {
|
||||
let tracks = self.value(forKey: #keyPath(StoreApp._releaseTracks)) as? NSOrderedSet
|
||||
return tracks
|
||||
}
|
||||
}
|
||||
|
||||
@objc(StoreApp11To17_1MigrationPolicy)
|
||||
class StoreApp11To17_1MigrationPolicy: StoreApp11To17MigrationPolicy
|
||||
{
|
||||
override func createDestinationInstances(forSource sInstance: NSManagedObject, in mapping: NSEntityMapping, manager: NSMigrationManager) throws {
|
||||
try super.createDestinationInstances(forSource: sInstance, in: mapping, manager: manager)
|
||||
}
|
||||
|
||||
override func createRelationships(forDestination dInstance: NSManagedObject, in mapping: NSEntityMapping, manager: NSMigrationManager) throws
|
||||
{
|
||||
try super.createRelationships(forDestination: dInstance, in: mapping, manager: manager)
|
||||
|
||||
let appBundleID = dInstance.value(forKey: #keyPath(StoreApp.bundleIdentifier))
|
||||
let sourceID = dInstance.value(forKey: #keyPath(StoreApp.sourceIdentifier))
|
||||
|
||||
for case let track as NSManagedObject in dInstance.storeAppReleaseTracks ?? []
|
||||
{
|
||||
track.setValue(appBundleID, forKey: #keyPath(ReleaseTrack._appBundleID))
|
||||
track.setValue(sourceID, forKey: #keyPath(ReleaseTrack._sourceID))
|
||||
|
||||
guard let releases = track.value(forKey: #keyPath(ReleaseTrack._releases)) as? NSOrderedSet else {
|
||||
continue
|
||||
}
|
||||
|
||||
for case let version as NSManagedObject in releases {
|
||||
version.setValue(appBundleID, forKey: #keyPath(AppVersion.appBundleID))
|
||||
version.setValue(sourceID, forKey: #keyPath(AppVersion.sourceID))
|
||||
}
|
||||
}
|
||||
|
||||
if let permissions = dInstance.value(forKey: #keyPath(StoreApp._permissions)) as? NSSet {
|
||||
for case let permission as NSManagedObject in permissions {
|
||||
permission.setValue(appBundleID, forKey: #keyPath(AppPermission.appBundleID))
|
||||
permission.setValue(sourceID, forKey: #keyPath(AppPermission.sourceID))
|
||||
}
|
||||
}
|
||||
|
||||
if let screenshots = dInstance.value(forKey: #keyPath(StoreApp._screenshots)) as? NSOrderedSet {
|
||||
for case let screenshot as NSManagedObject in screenshots {
|
||||
screenshot.setValue(appBundleID, forKey: #keyPath(AppScreenshot.appBundleID))
|
||||
screenshot.setValue(sourceID, forKey: #keyPath(AppScreenshot.sourceID))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
//
|
||||
// AppPermission17to17_1MigrationPolicy.swift
|
||||
// AltStore
|
||||
//
|
||||
// Created by Magesh K on 15/03/25.
|
||||
// Copyright © 2025 SideStore. All rights reserved.
|
||||
//
|
||||
|
||||
import CoreData
|
||||
|
||||
@objc(AppPermission17To17_1MigrationPolicy)
|
||||
class AppPermission17To17_1MigrationPolicy: NSEntityMigrationPolicy {
|
||||
|
||||
override func createDestinationInstances(forSource sInstance: NSManagedObject, in mapping: NSEntityMapping, manager: NSMigrationManager) throws {
|
||||
// Let the default implementation create the basic destination AppPermission
|
||||
try super.createDestinationInstances(forSource: sInstance, in: mapping, manager: manager)
|
||||
|
||||
// Get the destination AppPermission instance that was created
|
||||
guard let destinationPermission = manager.destinationInstances(forEntityMappingName: mapping.name, sourceInstances: [sInstance]).first else {
|
||||
print("Failed to locate destination AppPermission instance")
|
||||
return
|
||||
}
|
||||
|
||||
// Extract the type value from source
|
||||
if let type = sInstance.value(forKey: #keyPath(AppPermission.type)) as? String {
|
||||
// this is for backwards compatibility <0.5.10
|
||||
// if older type was a valid permission, then consider it as "privacy" in the newer "type".
|
||||
if let permission = self.derivePermissionFromType(type) {
|
||||
destinationPermission.setValue(permission, forKey: #keyPath(AppPermission._permission))
|
||||
destinationPermission.setValue("privacy", forKey: #keyPath(AppPermission.type))
|
||||
}
|
||||
}
|
||||
|
||||
// set initial values copied from source as-is
|
||||
// (will be updated by StoreApp and Source migration policy in its createRelationship() method)
|
||||
if let storeApp = sInstance.value(forKey: #keyPath(AppPermission.app)) as? NSManagedObject{
|
||||
if let appBundle = storeApp.value(forKey: #keyPath(StoreApp.bundleIdentifier)) as? String{
|
||||
destinationPermission.setValue(appBundle, forKey: #keyPath(AppPermission.appBundleID))
|
||||
}
|
||||
|
||||
if let sourceID = storeApp.value(forKey: #keyPath(StoreApp.sourceIdentifier)) as? String {
|
||||
destinationPermission.setValue(sourceID, forKey: #keyPath(AppPermission.sourceID))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
override func createRelationships(
|
||||
forDestination dInstance: NSManagedObject,
|
||||
in mapping: NSEntityMapping,
|
||||
manager: NSMigrationManager
|
||||
) throws {
|
||||
|
||||
try super.createRelationships(forDestination: dInstance, in: mapping, manager: manager)
|
||||
|
||||
// Retrieve the source storeApp from the source appPermission
|
||||
guard let storeApp = dInstance.value(forKey: #keyPath(AppPermission.app)) as? NSManagedObject else {
|
||||
print("Destination \(AppPermission.description()) has no storeApp")
|
||||
return
|
||||
}
|
||||
|
||||
// set initial values copied from source as-is to satisfy unique constraints
|
||||
// (will be updated by StoreApp and Source migration policy in its createRelationship() method)
|
||||
if let appBundle = storeApp.value(forKey: #keyPath(StoreApp.bundleIdentifier)) as? String{
|
||||
dInstance.setValue(appBundle, forKey: #keyPath(AppPermission.appBundleID))
|
||||
}
|
||||
|
||||
if let sourceID = storeApp.value(forKey: #keyPath(StoreApp.sourceIdentifier)) as? String {
|
||||
dInstance.setValue(sourceID, forKey: #keyPath(AppPermission.sourceID))
|
||||
}
|
||||
}
|
||||
|
||||
// Helper method to derive permission string from type
|
||||
private func derivePermissionFromType(_ type: String) -> String? {
|
||||
|
||||
// Based on the code in the documents, we need to map the ALTAppPermissionType to permission strings
|
||||
switch type {
|
||||
case "photos": return "NSPhotosUsageDescription"
|
||||
case "camera": return "NSCameraUsageDescription"
|
||||
case "location": return "NSLocationUsageDescription"
|
||||
case "contacts": return "NSContactsUsageDescription"
|
||||
case "reminders": return "NSRemindersUsageDescription"
|
||||
case "music": return "NSAppleMusicUsageDescription"
|
||||
case "microphone": return "NSMicrophoneUsageDescription"
|
||||
case "speech-recognition": return "NSSpeechRecognitionUsageDescription"
|
||||
case "background-audio": return "NSBackgroundAudioUsageDescription"
|
||||
case "background-fetch": return "NSBackgroundFetchUsageDescription"
|
||||
case "bluetooth": return "NSBluetoothUsageDescription"
|
||||
case "network": return "NSNetworkUsageDescription"
|
||||
case "calendars": return "NSCalendarsUsageDescription"
|
||||
case "touchID": return "NSTouchIDUsageDescription"
|
||||
case "faceID": return "NSFaceIDUsageDescription"
|
||||
case "siri": return "NSSiriUsageDescription"
|
||||
case "motion": return "NSMotionUsageDescription"
|
||||
|
||||
default: return nil // Default fallback
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
//
|
||||
// ReleaseTrack17To17_1MigrationPolicy.swift
|
||||
// AltStore
|
||||
//
|
||||
// Created by Magesh K on 15/03/25.
|
||||
// Copyright © 2025 SideStore. All rights reserved.
|
||||
//
|
||||
|
||||
import CoreData
|
||||
|
||||
@objc(ReleaseTrack17To17_1MigrationPolicy)
|
||||
class ReleaseTrack17To17_1MigrationPolicy: NSEntityMigrationPolicy {
|
||||
|
||||
override func createDestinationInstances(forSource sInstance: NSManagedObject, in mapping: NSEntityMapping, manager: NSMigrationManager) throws {
|
||||
try super.createDestinationInstances(forSource: sInstance, in: mapping, manager: manager)
|
||||
}
|
||||
|
||||
|
||||
override func createRelationships(
|
||||
forDestination dInstance: NSManagedObject,
|
||||
in mapping: NSEntityMapping,
|
||||
manager: NSMigrationManager
|
||||
) throws {
|
||||
|
||||
try super.createRelationships(forDestination: dInstance, in: mapping, manager: manager)
|
||||
|
||||
// Retrieve the source storeApp from the source ReleaseTrack
|
||||
guard let storeApp = dInstance.value(forKey: #keyPath(ReleaseTrack.storeApp)) as? NSManagedObject else {
|
||||
print("Destination \(ReleaseTrack.description()) has no storeApp")
|
||||
return
|
||||
}
|
||||
|
||||
// set initial values copied from source as-is to satisfy unique constraints
|
||||
// (will be updated by StoreApp and Source migration policy in its createRelationship() method)
|
||||
let appBundle = storeApp.value(forKey: #keyPath(StoreApp.bundleIdentifier)) as? String
|
||||
let sourceID = storeApp.value(forKey: #keyPath(StoreApp.sourceIdentifier)) as? String
|
||||
|
||||
if let appBundle {
|
||||
dInstance.setValue(appBundle, forKey: #keyPath(ReleaseTrack._appBundleID))
|
||||
}
|
||||
|
||||
if let sourceID {
|
||||
dInstance.setValue(sourceID, forKey: #keyPath(ReleaseTrack._sourceID))
|
||||
}
|
||||
|
||||
if let releases = dInstance.value(forKey: #keyPath(ReleaseTrack._releases)) as? NSOrderedSet {
|
||||
for case let version as NSManagedObject in releases {
|
||||
if let appBundle {
|
||||
version.setValue(appBundle, forKey: #keyPath(AppVersion.appBundleID))
|
||||
}
|
||||
if let sourceID {
|
||||
version.setValue(sourceID, forKey: #keyPath(AppVersion.sourceID))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,191 @@
|
||||
//
|
||||
// Source17To17_1MigrationPolicy.swift
|
||||
// AltStore
|
||||
//
|
||||
// Created by Magesh K on 15/03/25.
|
||||
// Copyright © 2025 SideStore. All rights reserved.
|
||||
//
|
||||
|
||||
import CoreData
|
||||
|
||||
fileprivate extension NSManagedObject
|
||||
{
|
||||
var sourceSourceURL: URL? {
|
||||
let sourceURL = self.value(forKey: #keyPath(Source.sourceURL)) as? URL
|
||||
return sourceURL
|
||||
}
|
||||
|
||||
var sourceSourceId: String? {
|
||||
let sourceId = self.value(forKey: #keyPath(Source.identifier)) as? String
|
||||
return sourceId
|
||||
}
|
||||
|
||||
var sourceApps: NSOrderedSet? {
|
||||
let apps = self.value(forKey: #keyPath(Source._apps)) as? NSOrderedSet
|
||||
return apps
|
||||
}
|
||||
|
||||
var sourceNewsItems: NSOrderedSet? {
|
||||
let newsItems = self.value(forKey: #keyPath(Source._newsItems)) as? NSOrderedSet
|
||||
return newsItems
|
||||
}
|
||||
}
|
||||
|
||||
fileprivate extension NSManagedObject
|
||||
{
|
||||
func setSourceId(_ sourceID: String)
|
||||
{
|
||||
self.setValue(sourceID, forKey: #keyPath(Source.identifier))
|
||||
}
|
||||
|
||||
func setGroupId(_ groupID: String)
|
||||
{
|
||||
self.setValue(groupID, forKey: #keyPath(Source.groupID))
|
||||
}
|
||||
|
||||
func setSourceSourceUrl(_ sourceURL: URL)
|
||||
{
|
||||
self.setValue(sourceURL, forKey: #keyPath(Source.sourceURL))
|
||||
}
|
||||
|
||||
func setSourceSourceID(_ sourceID: String)
|
||||
{
|
||||
self.setValue(sourceID, forKey: #keyPath(Source.identifier))
|
||||
}
|
||||
|
||||
func setStoreAppSourceID(_ sourceID: String)
|
||||
{
|
||||
self.setValue(sourceID, forKey: #keyPath(StoreApp.sourceIdentifier))
|
||||
}
|
||||
|
||||
func setNewsItemSourceID(_ sourceID: String)
|
||||
{
|
||||
self.setValue(sourceID, forKey: #keyPath(NewsItem.sourceIdentifier))
|
||||
}
|
||||
|
||||
func setAppVersionSourceID(_ sourceID: String)
|
||||
{
|
||||
self.setValue(sourceID, forKey: #keyPath(AppVersion.sourceID))
|
||||
}
|
||||
|
||||
func setAppPermissionSourceID(_ sourceID: String)
|
||||
{
|
||||
self.setValue(sourceID, forKey: #keyPath(AppPermission.sourceID))
|
||||
}
|
||||
|
||||
func setAppScreenshotSourceID(_ sourceID: String)
|
||||
{
|
||||
self.setValue(sourceID, forKey: #keyPath(AppScreenshot.sourceID))
|
||||
}
|
||||
|
||||
func setReleaseTracksSourceID(_ sourceID: String)
|
||||
{
|
||||
self.setValue(sourceID, forKey: #keyPath(ReleaseTrack._sourceID))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fileprivate extension NSManagedObject
|
||||
{
|
||||
var storeAppVersions: NSOrderedSet? {
|
||||
let versions = self.value(forKey: #keyPath(StoreApp._versions)) as? NSOrderedSet
|
||||
return versions
|
||||
}
|
||||
|
||||
var storeAppPermissions: NSSet? {
|
||||
let permissions = self.value(forKey: #keyPath(StoreApp._permissions)) as? NSSet
|
||||
return permissions
|
||||
}
|
||||
|
||||
var storeAppScreenshots: NSOrderedSet? {
|
||||
let screenshots = self.value(forKey: #keyPath(StoreApp._screenshots)) as? NSOrderedSet
|
||||
return screenshots
|
||||
}
|
||||
|
||||
var storeAppReleaseTracks: NSOrderedSet? {
|
||||
let tracks = self.value(forKey: #keyPath(StoreApp._releaseTracks)) as? NSOrderedSet
|
||||
return tracks
|
||||
}
|
||||
}
|
||||
|
||||
@objc(Source17To17_1MigrationPolicy)
|
||||
class Source17To17_1MigrationPolicy: NSEntityMigrationPolicy
|
||||
{
|
||||
override func createDestinationInstances(forSource sInstance: NSManagedObject, in mapping: NSEntityMapping, manager: NSMigrationManager) throws {
|
||||
// Let the default implementation create the basic destination AppPermission
|
||||
try super.createDestinationInstances(forSource: sInstance, in: mapping, manager: manager)
|
||||
|
||||
// Get the destination Source instance that was created
|
||||
guard let dInstance = manager.destinationInstances(forEntityMappingName: mapping.name, sourceInstances: [sInstance]).first else {
|
||||
print("Failed to locate destination Source instance")
|
||||
return
|
||||
}
|
||||
|
||||
// update new fields with initial values
|
||||
if let sourceID = sInstance.value(forKey: #keyPath(Source.identifier)) as? String {
|
||||
dInstance.setValue(sourceID, forKey: #keyPath(Source.groupID))
|
||||
}
|
||||
|
||||
guard var sourceURL = dInstance.sourceSourceURL else {
|
||||
return
|
||||
}
|
||||
|
||||
// sidestore official source has been moved to sidestore.io/apps-v2.json
|
||||
// if we don't switch, users will end up with 2 offical sources
|
||||
let normalizedSourceURL = try? sourceURL.normalized()
|
||||
if normalizedSourceURL == "apps.sidestore.io" // if using old source url (<0.5.9)
|
||||
{
|
||||
sourceURL = Source.altStoreSourceURL // switch to latest
|
||||
dInstance.setSourceSourceUrl(sourceURL) // and use it for current
|
||||
}
|
||||
|
||||
var sourceID = try Source.sourceID(from: sourceURL)
|
||||
dInstance.setSourceId(sourceID)
|
||||
|
||||
// for older versions migrating to current (their sourceID is their groupID)
|
||||
dInstance.setGroupId(sourceID)
|
||||
|
||||
if sourceID == "apps.sidestore.io" {
|
||||
sourceID = Source.altStoreIdentifier
|
||||
dInstance.setSourceId(sourceID)
|
||||
}
|
||||
}
|
||||
|
||||
override func createRelationships(forDestination dInstance: NSManagedObject, in mapping: NSEntityMapping, manager: NSMigrationManager) throws
|
||||
{
|
||||
try super.createRelationships(forDestination: dInstance, in: mapping, manager: manager)
|
||||
|
||||
guard let sourceID = dInstance.sourceSourceId else { return }
|
||||
|
||||
for case let newsItem as NSManagedObject in dInstance.sourceNewsItems ?? []
|
||||
{
|
||||
newsItem.setNewsItemSourceID(sourceID)
|
||||
}
|
||||
|
||||
for case let app as NSManagedObject in dInstance.sourceApps ?? []
|
||||
{
|
||||
app.setStoreAppSourceID(sourceID)
|
||||
|
||||
for case let screenshot as NSManagedObject in app.storeAppScreenshots ?? []
|
||||
{
|
||||
screenshot.setAppScreenshotSourceID(sourceID)
|
||||
}
|
||||
|
||||
for case let track as NSManagedObject in app.storeAppReleaseTracks ?? []
|
||||
{
|
||||
// print("Source_17_1MigrationPolicy: processing track \(track.value(forKey: "track")!)")
|
||||
track.setValue(sourceID, forKey: #keyPath(ReleaseTrack._sourceID))
|
||||
|
||||
guard let releases = track.value(forKey: #keyPath(ReleaseTrack._releases)) as? NSOrderedSet else {
|
||||
// print("Source_17_1MigrationPolicy: releases not found for track: \(track.value(forKey: "track")!)")
|
||||
continue
|
||||
}
|
||||
|
||||
for case let version as NSManagedObject in releases {
|
||||
// print("Source_17_1MigrationPolicy: updating sourceID for version: \(version.value(forKey: "version")!)")
|
||||
version.setValue(sourceID, forKey: #keyPath(AppVersion.sourceID))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
//
|
||||
// StoreApp17To17_1MigrationPolicy.swift
|
||||
// AltStore
|
||||
//
|
||||
// Created by Magesh K on 15/03/25.
|
||||
// Copyright © 2025 SideStore. All rights reserved.
|
||||
//
|
||||
|
||||
import CoreData
|
||||
|
||||
fileprivate extension NSManagedObject
|
||||
{
|
||||
var storeAppReleaseTracks: NSOrderedSet? {
|
||||
let tracks = self.value(forKey: #keyPath(StoreApp._releaseTracks)) as? NSOrderedSet
|
||||
return tracks
|
||||
}
|
||||
}
|
||||
|
||||
@objc(StoreApp17To17_1MigrationPolicy)
|
||||
class StoreApp17To17_1MigrationPolicy: NSEntityMigrationPolicy
|
||||
{
|
||||
override func createDestinationInstances(forSource sInstance: NSManagedObject, in mapping: NSEntityMapping, manager: NSMigrationManager) throws {
|
||||
try super.createDestinationInstances(forSource: sInstance, in: mapping, manager: manager)
|
||||
}
|
||||
|
||||
override func createRelationships(forDestination dInstance: NSManagedObject, in mapping: NSEntityMapping, manager: NSMigrationManager) throws
|
||||
{
|
||||
try super.createRelationships(forDestination: dInstance, in: mapping, manager: manager)
|
||||
|
||||
let appBundleID = dInstance.value(forKey: #keyPath(StoreApp.bundleIdentifier))
|
||||
|
||||
for case let track as NSManagedObject in dInstance.storeAppReleaseTracks ?? []
|
||||
{
|
||||
track.setValue(appBundleID, forKey: #keyPath(ReleaseTrack._appBundleID))
|
||||
|
||||
guard let releases = track.value(forKey: #keyPath(ReleaseTrack._releases)) as? NSOrderedSet else {
|
||||
continue
|
||||
}
|
||||
|
||||
for case let version as NSManagedObject in releases {
|
||||
version.setValue(appBundleID, forKey: #keyPath(AppVersion.appBundleID))
|
||||
}
|
||||
}
|
||||
|
||||
if let permissions = dInstance.value(forKey: #keyPath(StoreApp._permissions)) as? NSSet {
|
||||
for case let permission as NSManagedObject in permissions {
|
||||
permission.setValue(appBundleID, forKey: #keyPath(AppPermission.appBundleID))
|
||||
}
|
||||
}
|
||||
|
||||
if let screenshots = dInstance.value(forKey: #keyPath(StoreApp._screenshots)) as? NSOrderedSet {
|
||||
for case let screenshot as NSManagedObject in screenshots {
|
||||
screenshot.setValue(appBundleID, forKey: #keyPath(AppScreenshot.appBundleID))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -75,6 +75,9 @@ public class NewsItem: BaseEntity, Decodable
|
||||
self.imageURL = try container.decodeIfPresent(URL.self, forKey: .imageURL)
|
||||
self.externalURL = try container.decodeIfPresent(URL.self, forKey: .externalURL)
|
||||
|
||||
// TODO: app specific news should be moved to appEntity (via refactoring)
|
||||
// This can be done by: 1. having two newsItem schema, one for source and one for StoreApp
|
||||
// 2. move this appID field into the newItem schema which is under StoreApp.
|
||||
self.appID = try container.decodeIfPresent(String.self, forKey: .appID)
|
||||
|
||||
let notify = try container.decodeIfPresent(Bool.self, forKey: .notify) ?? false
|
||||
|
||||
@@ -14,7 +14,9 @@ public class ReleaseTrack: BaseEntity, Decodable
|
||||
{
|
||||
// attributes
|
||||
@NSManaged @objc(track) public private(set) var _track: String?
|
||||
|
||||
@NSManaged @objc(appBundleID) public private(set) var _appBundleID: String?
|
||||
@NSManaged @objc(sourceID) public private(set) var _sourceID: String?
|
||||
|
||||
// RelationShips
|
||||
@NSManaged @objc(releases) public private(set) var _releases: NSOrderedSet?
|
||||
@NSManaged public private(set) var storeApp: StoreApp?
|
||||
@@ -89,7 +91,7 @@ public extension ReleaseTrack{
|
||||
}
|
||||
|
||||
// update it into the appVersion
|
||||
_ = version.mutateForData(channel: track, appBundleID: storeApp.bundleIdentifier)
|
||||
_ = version.mutateForData(channel: track, appBundleID: storeApp.bundleIdentifier, sourceID: storeApp.sourceIdentifier)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,6 +111,10 @@ public extension ReleaseTrack{
|
||||
if key == NSExpression(forKeyPath: #keyPath(ReleaseTrack.storeApp)).keyPath
|
||||
{
|
||||
updateVersions(for: storeApp)
|
||||
|
||||
// update unique constraint attribs
|
||||
self._appBundleID = storeApp?.bundleIdentifier
|
||||
self._sourceID = storeApp?.sourceIdentifier
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,11 @@ import UIKit
|
||||
|
||||
public extension Source
|
||||
{
|
||||
static let altStoreIdentifier = try! Source.sourceID(from: Source.altStoreSourceURL)
|
||||
#if ALPHA
|
||||
static let altStoreGroupIdentifier = Bundle.Info.appbundleIdentifier
|
||||
#else
|
||||
static let altStoreGroupIdentifier = Bundle.Info.appbundleIdentifier
|
||||
#endif
|
||||
|
||||
#if STAGING
|
||||
|
||||
@@ -24,13 +28,15 @@ public extension Source
|
||||
#else
|
||||
|
||||
#if ALPHA
|
||||
static let altStoreSourceURL = URL(string: "https://apps.sidestore.io/")!
|
||||
static let altStoreSourceURL = URL(string: "https://sidestore.io/apps-v2.json/")!
|
||||
#else
|
||||
// static let altStoreSourceURL = URL(string: "https://apps.sidestore.io/")!
|
||||
static let altStoreSourceURL = URL(string: "https://sidestore.io/apps-v2.json/")! // using v2 for alpha releases
|
||||
static let altStoreSourceURL = URL(string: "https://sidestore.io/apps-v2.json/")!
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
// normalized url is the source identifier (or) p-key!
|
||||
static let altStoreIdentifier = try! Source.sourceID(from: altStoreSourceURL)
|
||||
}
|
||||
|
||||
// public struct AppPermissionFeed: Codable {
|
||||
@@ -205,7 +211,8 @@ public class Source: BaseEntity, Decodable
|
||||
/* Properties */
|
||||
@NSManaged public var version: Int
|
||||
@NSManaged public var name: String
|
||||
@NSManaged public private(set) var identifier: String
|
||||
@NSManaged public private(set) var identifier: String // NOTE: sourceID is just normalized sourceURL
|
||||
@NSManaged public private(set) var groupID: String?
|
||||
@NSManaged public var sourceURL: URL
|
||||
|
||||
/* Source Detail */
|
||||
@@ -280,6 +287,9 @@ public class Source: BaseEntity, Decodable
|
||||
case news
|
||||
case featuredApps
|
||||
case userInfo
|
||||
|
||||
// case identifier
|
||||
case groupID = "identifier"
|
||||
}
|
||||
|
||||
private override init(entity: NSEntityDescription, insertInto context: NSManagedObjectContext?)
|
||||
@@ -359,6 +369,24 @@ public class Source: BaseEntity, Decodable
|
||||
|
||||
// Updates identifier + apps & newsItems
|
||||
try self.setSourceURL(sourceURL)
|
||||
|
||||
|
||||
// NOTE: Source ID is just normalized sourceURL. coz normalized url is the primary key which needs to be unique
|
||||
// Hence if a source's URL changed, then it means it is a different source now.
|
||||
// This also means that the identifier field in the source is irrelevant (if any)
|
||||
|
||||
// if we want grouping of sources from same author or something like that then we should have used groupID (a new field)
|
||||
// shouldn't use the existing "identifier" field, hence the following is commented out
|
||||
|
||||
// // if an explicit identifier is present, then use it
|
||||
// if let identifier = try container.decodeIfPresent(String.self, forKey: .identifier)
|
||||
// {
|
||||
// self.identifier = identifier
|
||||
// }
|
||||
|
||||
// if an explicit (group)identifier is present, then use it as groupID else use sourceID as groupID too
|
||||
self.groupID = try container.decodeIfPresent(String.self, forKey: .groupID) ?? self.identifier
|
||||
|
||||
}
|
||||
catch
|
||||
{
|
||||
@@ -405,7 +433,7 @@ public extension Source
|
||||
|
||||
// TODO: Support alternate URLs
|
||||
let isRecommended = recommendedSources.contains { source in
|
||||
return source.identifier == self.identifier || source.sourceURL?.absoluteString.lowercased() == self.sourceURL.absoluteString
|
||||
return source.identifier == self.identifier || source.sourceURL?.absoluteString.lowercased() == self.sourceURL.absoluteString.lowercased()
|
||||
}
|
||||
return isRecommended
|
||||
}
|
||||
@@ -418,14 +446,17 @@ public extension Source
|
||||
}
|
||||
}
|
||||
|
||||
internal extension Source
|
||||
public extension Source
|
||||
{
|
||||
class func sourceID(from sourceURL: URL) throws -> String
|
||||
{
|
||||
let sourceID = try sourceURL.normalized()
|
||||
return sourceID
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
internal extension Source
|
||||
{
|
||||
func setFeaturedApps(_ featuredApps: [StoreApp]?)
|
||||
{
|
||||
// Explicitly update relationships for all apps to ensure featuredApps merges correctly.
|
||||
@@ -451,17 +482,23 @@ public extension Source
|
||||
{
|
||||
func setSourceURL(_ sourceURL: URL) throws
|
||||
{
|
||||
let identifier = try Source.sourceID(from: sourceURL)
|
||||
|
||||
self.identifier = identifier
|
||||
self.sourceURL = sourceURL
|
||||
|
||||
// update the normalized sourceURL as the identifier
|
||||
let identifier = try Source.sourceID(from: sourceURL)
|
||||
try self.setSourceID(identifier)
|
||||
}
|
||||
|
||||
func setSourceID(_ identifier: String) throws
|
||||
{
|
||||
self.identifier = identifier
|
||||
|
||||
for app in self.apps
|
||||
{
|
||||
app.sourceIdentifier = identifier
|
||||
}
|
||||
|
||||
for newsItem in self.newsItems
|
||||
for newsItem in self.newsItems
|
||||
{
|
||||
newsItem.sourceIdentifier = identifier
|
||||
}
|
||||
@@ -479,6 +516,7 @@ public extension Source
|
||||
{
|
||||
let source = Source(context: context)
|
||||
source.name = "SideStore Offical"
|
||||
source.groupID = Source.altStoreGroupIdentifier
|
||||
source.identifier = Source.altStoreIdentifier
|
||||
try! source.setSourceURL(Source.altStoreSourceURL)
|
||||
|
||||
@@ -491,13 +529,14 @@ public extension Source
|
||||
return source
|
||||
}
|
||||
|
||||
class func make(name: String, identifier: String, sourceURL: URL, context: NSManagedObjectContext) -> Source
|
||||
class func make(name: String, groupID: String, sourceURL: URL, context: NSManagedObjectContext) -> Source
|
||||
{
|
||||
let source = Source(context: context)
|
||||
source.name = name
|
||||
source.identifier = identifier
|
||||
source.sourceURL = sourceURL
|
||||
|
||||
source.sourceURL = sourceURL
|
||||
source.identifier = try! Source.sourceID(from: sourceURL)
|
||||
|
||||
return source
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
// Configuration settings file format documentation can be found at:
|
||||
// https://help.apple.com/xcode/#/dev745c5c974
|
||||
|
||||
MARKETING_VERSION = 0.6.0
|
||||
CURRENT_PROJECT_VERSION = 6000
|
||||
MARKETING_VERSION = 0.6.1
|
||||
CURRENT_PROJECT_VERSION = 0601
|
||||
|
||||
// Vars to be overwritten by `CodeSigning.xcconfig` if exists
|
||||
DEVELOPMENT_TEAM = S32Z3HMYVQ
|
||||
|
||||
54
SideStore/Utils/common/BuildInfo.swift
Normal file
54
SideStore/Utils/common/BuildInfo.swift
Normal file
@@ -0,0 +1,54 @@
|
||||
//
|
||||
// BuildInfo.swift
|
||||
// AltStore
|
||||
//
|
||||
// Created by Magesh K on 23/03/25.
|
||||
// Copyright © 2025 SideStore. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
public class BuildInfo{
|
||||
private static let MARKETING_VERSION_TAG = "CFBundleShortVersionString"
|
||||
private static let CURRENT_PROJECT_VERSION_TAG = kCFBundleVersionKey as String
|
||||
|
||||
private static let XCODE_VERSION_TAG = "DTXcode"
|
||||
private static let XCODE_REVISION_TAG = "DTXcodeBuild"
|
||||
|
||||
let bundle: Bundle
|
||||
|
||||
public init(){
|
||||
bundle = Bundle.main
|
||||
}
|
||||
|
||||
enum BundleError: Swift.Error {
|
||||
case invalidURL
|
||||
}
|
||||
|
||||
public init(url: URL) throws {
|
||||
guard let bundle = Bundle(url: url) else {
|
||||
throw BundleError.invalidURL
|
||||
}
|
||||
self.bundle = bundle
|
||||
}
|
||||
|
||||
public lazy var project_version: String? = {
|
||||
let version = bundle.object(forInfoDictionaryKey: Self.CURRENT_PROJECT_VERSION_TAG) as? String
|
||||
return version
|
||||
}()
|
||||
|
||||
public lazy var marketing_version: String? = {
|
||||
let version = bundle.object(forInfoDictionaryKey: Self.MARKETING_VERSION_TAG) as? String
|
||||
return version
|
||||
}()
|
||||
|
||||
public lazy var xcode: String? = {
|
||||
let xcode = bundle.object(forInfoDictionaryKey: Self.XCODE_VERSION_TAG) as? String
|
||||
return xcode
|
||||
}()
|
||||
|
||||
public lazy var xcode_revision: String? = {
|
||||
let revision = bundle.object(forInfoDictionaryKey: Self.XCODE_REVISION_TAG) as? String
|
||||
return revision
|
||||
}()
|
||||
}
|
||||
Reference in New Issue
Block a user