Revert "- Fixed: attempt migrations fix from 0.5.10 to 0.6.0"

This reverts commit ae8e9a3506.
This commit is contained in:
mahee96
2025-03-23 11:57:16 -07:00
parent 117f31e158
commit cbde3e6495
9 changed files with 840 additions and 955 deletions

View File

@@ -69,7 +69,6 @@
A81A8CD12D68BA9B0086C96F /* TreeMap.swift in Sources */ = {isa = PBXBuildFile; fileRef = A81A8CB02D68B0320086C96F /* TreeMap.swift */; }; A81A8CD12D68BA9B0086C96F /* TreeMap.swift in Sources */ = {isa = PBXBuildFile; fileRef = A81A8CB02D68B0320086C96F /* TreeMap.swift */; };
A81A8CD22D68BAA30086C96F /* SingletonGenericMap.swift in Sources */ = {isa = PBXBuildFile; fileRef = A868CFE32D319988002F1201 /* SingletonGenericMap.swift */; }; A81A8CD22D68BAA30086C96F /* SingletonGenericMap.swift in Sources */ = {isa = PBXBuildFile; fileRef = A868CFE32D319988002F1201 /* SingletonGenericMap.swift */; };
A81A8CD42D68BAFF0086C96F /* DataStructureTests.xctestplan in Resources */ = {isa = PBXBuildFile; fileRef = A81A8CD32D68BAFF0086C96F /* DataStructureTests.xctestplan */; }; A81A8CD42D68BAFF0086C96F /* DataStructureTests.xctestplan in Resources */ = {isa = PBXBuildFile; fileRef = A81A8CD32D68BAFF0086C96F /* DataStructureTests.xctestplan */; };
A81BF93D2D7FA94D00768940 /* AppPermission11To17MigrationPolicy.swift in Sources */ = {isa = PBXBuildFile; fileRef = A81BF93C2D7FA94D00768940 /* AppPermission11To17MigrationPolicy.swift */; };
A82067842D03DC0600645C0D /* OperatingSystemVersion+Comparable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5708416292448DA00D42D34 /* OperatingSystemVersion+Comparable.swift */; }; A82067842D03DC0600645C0D /* OperatingSystemVersion+Comparable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5708416292448DA00D42D34 /* OperatingSystemVersion+Comparable.swift */; };
A82067C42D03E0DE00645C0D /* SemanticVersion in Frameworks */ = {isa = PBXBuildFile; productRef = A82067C32D03E0DE00645C0D /* SemanticVersion */; }; A82067C42D03E0DE00645C0D /* SemanticVersion in Frameworks */ = {isa = PBXBuildFile; productRef = A82067C32D03E0DE00645C0D /* SemanticVersion */; };
A8228B5B2D6E2C0C00F7CE0E /* (null) in Sources */ = {isa = PBXBuildFile; }; A8228B5B2D6E2C0C00F7CE0E /* (null) in Sources */ = {isa = PBXBuildFile; };
@@ -668,7 +667,6 @@
A81A8CC52D68BA610086C96F /* DataStructureTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DataStructureTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 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>"; }; 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>"; }; A81A8CD32D68BAFF0086C96F /* DataStructureTests.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = DataStructureTests.xctestplan; sourceTree = "<group>"; };
A81BF93C2D7FA94D00768940 /* AppPermission11To17MigrationPolicy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppPermission11To17MigrationPolicy.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>"; }; 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>"; }; 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>"; }; A85ACB8F2D1F31C400AA3DE7 /* AltStore.debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AltStore.debug.xcconfig; sourceTree = "<group>"; };
@@ -1827,7 +1825,6 @@
BF66EEAE2501AECA007EE018 /* StoreAppPolicy.swift */, BF66EEAE2501AECA007EE018 /* StoreAppPolicy.swift */,
D5F99A1928D12B1400476A16 /* StoreApp10ToStoreApp11Policy.swift */, D5F99A1928D12B1400476A16 /* StoreApp10ToStoreApp11Policy.swift */,
A881E7CA2D6EF5AB00954AD2 /* StoreApp11To17MigrationPolicy.swift */, A881E7CA2D6EF5AB00954AD2 /* StoreApp11To17MigrationPolicy.swift */,
A81BF93C2D7FA94D00768940 /* AppPermission11To17MigrationPolicy.swift */,
); );
path = Policies; path = Policies;
sourceTree = "<group>"; sourceTree = "<group>";
@@ -3113,7 +3110,6 @@
BFAECC522501B0A400528F27 /* CodableError.swift in Sources */, BFAECC522501B0A400528F27 /* CodableError.swift in Sources */,
A8FD915F2D046F5200322782 /* UserInfoValue.swift in Sources */, A8FD915F2D046F5200322782 /* UserInfoValue.swift in Sources */,
D5F9821D2AB900060045751F /* AppScreenshot.swift in Sources */, D5F9821D2AB900060045751F /* AppScreenshot.swift in Sources */,
A81BF93D2D7FA94D00768940 /* AppPermission11To17MigrationPolicy.swift in Sources */,
BF66EE9E2501AEC1007EE018 /* Fetchable.swift in Sources */, BF66EE9E2501AEC1007EE018 /* Fetchable.swift in Sources */,
BF66EEDF2501AECA007EE018 /* PatreonAccount.swift in Sources */, BF66EEDF2501AECA007EE018 /* PatreonAccount.swift in Sources */,
BFAECC532501B0A400528F27 /* ServerProtocol.swift in Sources */, BFAECC532501B0A400528F27 /* ServerProtocol.swift in Sources */,

View File

@@ -222,6 +222,11 @@
<attribute name="track" optional="YES" attributeType="String"/> <attribute name="track" optional="YES" attributeType="String"/>
<relationship name="releases" optional="YES" toMany="YES" deletionRule="Cascade" ordered="YES" destinationEntity="AppVersion" inverseName="releaseTrack" inverseEntity="AppVersion"/> <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"/> <relationship name="storeApp" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="StoreApp" inverseName="releaseTracks" inverseEntity="StoreApp"/>
<uniquenessConstraints>
<uniquenessConstraint>
<constraint value="track"/>
</uniquenessConstraint>
</uniquenessConstraints>
</entity> </entity>
<entity name="Source" representedClassName="Source" syncable="YES"> <entity name="Source" representedClassName="Source" syncable="YES">
<attribute name="error" optional="YES" attributeType="Transformable" valueTransformerName="ALTSecureValueTransformer"/> <attribute name="error" optional="YES" attributeType="Transformable" valueTransformerName="ALTSecureValueTransformer"/>

View File

@@ -33,7 +33,7 @@ public class AppPermission: BaseEntity
default: return UnknownAppPermission(rawValue: self._permission) default: return UnknownAppPermission(rawValue: self._permission)
} }
} }
@NSManaged @objc(permission) private(set) public var _permission: String @NSManaged @objc(permission) private var _permission: String
// Set by StoreApp. // Set by StoreApp.
@NSManaged public var appBundleID: String @NSManaged public var appBundleID: String

View File

@@ -1,70 +0,0 @@
//
// AppPermission11To17MigrationPolicy.swift
// AltStore
//
// Created by Magesh K on 11/03/25.
// Copyright © 2025 SideStore. All rights reserved.
//
import CoreData
@objc(AppPermission11To17MigrationPolicy)
class AppPermission11To17MigrationPolicy: 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 AppPdestinationAppermission instance")
return
}
// Extract the type value from source
if let type = sInstance.value(forKey: #keyPath(AppPermission.type)) as? String {
// In the new model, "permission" is the actual permission string, which needs to be derived from the old "type"
let permission = self.derivePermissionFromType(type)
destinationPermission.setValue(permission, forKey: #keyPath(AppPermission._permission))
}
// 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 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))
}
}
}
// 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"
case "entitlement": return type // For entitlements, we might keep the raw value
case "privacy": return type // For privacy permissions, we might keep the raw value
default: return type // Default fallback
}
}
}

View File

@@ -15,11 +15,6 @@ fileprivate extension NSManagedObject
return sourceURL return sourceURL
} }
var sourceSourceId: String? {
let sourceId = self.value(forKey: #keyPath(Source.identifier)) as? String
return sourceId
}
var sourceApps: NSOrderedSet? { var sourceApps: NSOrderedSet? {
let apps = self.value(forKey: #keyPath(Source._apps)) as? NSOrderedSet let apps = self.value(forKey: #keyPath(Source._apps)) as? NSOrderedSet
return apps return apps
@@ -33,15 +28,10 @@ fileprivate extension NSManagedObject
fileprivate extension NSManagedObject fileprivate extension NSManagedObject
{ {
func setSourceId(_ sourceID: String) func setSourceSourceID(_ sourceID: String)
{ {
self.setValue(sourceID, forKey: #keyPath(Source.identifier)) self.setValue(sourceID, forKey: #keyPath(Source.identifier))
} }
func setSourceSourceUrl(_ sourceURL: URL)
{
self.setValue(sourceURL, forKey: #keyPath(Source.sourceURL))
}
func setStoreAppSourceID(_ sourceID: String) func setStoreAppSourceID(_ sourceID: String)
{ {
@@ -62,11 +52,6 @@ fileprivate extension NSManagedObject
{ {
self.setValue(sourceID, forKey: #keyPath(AppPermission.sourceID)) self.setValue(sourceID, forKey: #keyPath(AppPermission.sourceID))
} }
func setAppPermissionAppBundleID(_ appBundleID: String)
{
self.setValue(appBundleID, forKey: #keyPath(AppPermission.appBundleID))
}
func setAppScreenshotSourceID(_ sourceID: String) func setAppScreenshotSourceID(_ sourceID: String)
{ {
@@ -76,11 +61,6 @@ fileprivate extension NSManagedObject
fileprivate extension NSManagedObject fileprivate extension NSManagedObject
{ {
var bundleId: String? {
let bundleID = self.value(forKey: #keyPath(StoreApp.bundleIdentifier)) as? String
return bundleID
}
var storeAppVersions: NSOrderedSet? { var storeAppVersions: NSOrderedSet? {
let versions = self.value(forKey: #keyPath(StoreApp._versions)) as? NSOrderedSet let versions = self.value(forKey: #keyPath(StoreApp._versions)) as? NSOrderedSet
return versions return versions
@@ -108,28 +88,15 @@ class Source11To17MigrationPolicy: NSEntityMigrationPolicy
// Copied from Source.setSourceURL() // Copied from Source.setSourceURL()
// sidestore official source has been moved to sidestore.io/apps-v2.json // sidestore official soruce has been moved to sidestore.io/apps-v2.json
// if we don't switch, users will end up with 2 offical sources // if we don't switch, users will end up with 2 offical sources
if let host = sourceURL.host, if sourceURL.absoluteString.contains("apps.sidestore.io") // if using old source
host == "apps.sidestore.io" // if using old source
{ {
sourceURL = Source.altStoreSourceURL // switch to latest sourceURL = Source.altStoreSourceURL // switch to latest
dInstance.setSourceSourceUrl(sourceURL)
}
let sourceID: String
if let existingID = dInstance.sourceSourceId {
sourceID = existingID
} else {
sourceID = try Source.sourceID(from: sourceURL)
dInstance.setSourceId(sourceID)
}
if URL(string: sourceID)?.host == "apps.sidestore.io" || sourceID == Source.altStoreSourceURL.absoluteString
{
dInstance.setSourceId(Source.altStoreIdentifier)
} }
let sourceID = try Source.sourceID(from: sourceURL)
dInstance.setSourceSourceID(sourceID)
for case let newsItem as NSManagedObject in dInstance.sourceNewsItems ?? [] for case let newsItem as NSManagedObject in dInstance.sourceNewsItems ?? []
{ {
@@ -150,9 +117,6 @@ class Source11To17MigrationPolicy: NSEntityMigrationPolicy
for case let permission as NSManagedObject in app.storeAppPermissions ?? [] for case let permission as NSManagedObject in app.storeAppPermissions ?? []
{ {
permission.setAppPermissionSourceID(sourceID) permission.setAppPermissionSourceID(sourceID)
if let bundleID = app.bundleId {
permission.setAppPermissionAppBundleID(bundleID)
}
} }
for case let screenshot as NSManagedObject in app.storeAppScreenshots ?? [] for case let screenshot as NSManagedObject in app.storeAppScreenshots ?? []

View File

@@ -106,10 +106,9 @@ class StoreApp11To17MigrationPolicy: NSEntityMigrationPolicy {
return return
} }
// Create a new ReleaseTrack entity // Create a new ReleaseTrack entity
let context = dInstance.managedObjectContext! let context = dInstance.managedObjectContext!
let releaseTrack = NSEntityDescription.insertNewObject(forEntityName: ReleaseTrack.entity().name! ?? ReleaseTrack.description(), into: context) let releaseTrack = NSEntityDescription.insertNewObject(forEntityName: ReleaseTrack.entity().name!, into: context)
releaseTrack.setValue(defaultChannel, forKey: #keyPath(ReleaseTrack._track)) releaseTrack.setValue(defaultChannel, forKey: #keyPath(ReleaseTrack._track))
// Connect the releaseTrack to the destination StoreApp // Connect the releaseTrack to the destination StoreApp
@@ -117,7 +116,7 @@ class StoreApp11To17MigrationPolicy: NSEntityMigrationPolicy {
// Find the mapping name for AppVersion (make sure this exactly matches your mapping model) // Find the mapping name for AppVersion (make sure this exactly matches your mapping model)
let appVersionMappingName = findEntityMappingName(for: AppVersion.entity().name ?? AppVersion.description(), in: manager) let appVersionMappingName = findEntityMappingName(for: AppVersion.entity().name!, in: manager)
// Create a mutable ordered set for the destination AppVersion objects // Create a mutable ordered set for the destination AppVersion objects
let destinationVersionsSet = NSMutableOrderedSet() let destinationVersionsSet = NSMutableOrderedSet()
@@ -146,4 +145,5 @@ class StoreApp11To17MigrationPolicy: NSEntityMigrationPolicy {
// dInstance.setValue(NSOrderedSet(), forKey: #keyPath(StoreApp._versions)) // dInstance.setValue(NSOrderedSet(), forKey: #keyPath(StoreApp._versions))
dInstance.setValue(nil, forKey: #keyPath(StoreApp._versions)) dInstance.setValue(nil, forKey: #keyPath(StoreApp._versions))
} }
} }

View File

@@ -14,7 +14,7 @@ public class ReleaseTrack: BaseEntity, Decodable
{ {
// attributes // attributes
@NSManaged @objc(track) public private(set) var _track: String? @NSManaged @objc(track) public private(set) var _track: String?
// RelationShips // RelationShips
@NSManaged @objc(releases) public private(set) var _releases: NSOrderedSet? @NSManaged @objc(releases) public private(set) var _releases: NSOrderedSet?
@NSManaged public private(set) var storeApp: StoreApp? @NSManaged public private(set) var storeApp: StoreApp?

View File

@@ -11,7 +11,7 @@ import UIKit
public extension Source public extension Source
{ {
static let altStoreIdentifier = "com.SideStore.SideStore" static let altStoreIdentifier = try! Source.sourceID(from: Source.altStoreSourceURL)
#if STAGING #if STAGING
@@ -280,8 +280,6 @@ public class Source: BaseEntity, Decodable
case news case news
case featuredApps case featuredApps
case userInfo case userInfo
case identifier
} }
private override init(entity: NSEntityDescription, insertInto context: NSManagedObjectContext?) private override init(entity: NSEntityDescription, insertInto context: NSManagedObjectContext?)
@@ -306,9 +304,6 @@ public class Source: BaseEntity, Decodable
// use sourceversion = 1 by default if not specified in source json // use sourceversion = 1 by default if not specified in source json
self.version = try container.decodeIfPresent(Int.self, forKey: .version) ?? 1 self.version = try container.decodeIfPresent(Int.self, forKey: .version) ?? 1
// use sourceURL as identifier is one is not present for backwards compatibility
self.identifier = try container.decodeIfPresent(String.self, forKey: .identifier) ?? Source.sourceID(from: sourceURL)
self.subtitle = try container.decodeIfPresent(String.self, forKey: .subtitle) self.subtitle = try container.decodeIfPresent(String.self, forKey: .subtitle)
self.websiteURL = try container.decodeIfPresent(URL.self, forKey: .websiteURL) self.websiteURL = try container.decodeIfPresent(URL.self, forKey: .websiteURL)
self.localizedDescription = try container.decodeIfPresent(String.self, forKey: .localizedDescription) self.localizedDescription = try container.decodeIfPresent(String.self, forKey: .localizedDescription)
@@ -456,10 +451,9 @@ public extension Source
{ {
func setSourceURL(_ sourceURL: URL) throws func setSourceURL(_ sourceURL: URL) throws
{ {
// commented out to retain source id as-is (independent of sourceURL) let identifier = try Source.sourceID(from: sourceURL)
// let identifier = try Source.sourceID(from: sourceURL)
// self.identifier = identifier self.identifier = identifier
self.sourceURL = sourceURL self.sourceURL = sourceURL
for app in self.apps for app in self.apps