mirror of
https://github.com/SideStore/SideStore.git
synced 2026-02-09 06:43:25 +01:00
- Fixed: attempt migrations fix from 0.5.10 to 0.6.0
This commit is contained in:
@@ -69,6 +69,7 @@
|
|||||||
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; };
|
||||||
@@ -667,6 +668,7 @@
|
|||||||
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>"; };
|
||||||
@@ -1825,6 +1827,7 @@
|
|||||||
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>";
|
||||||
@@ -3110,6 +3113,7 @@
|
|||||||
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 */,
|
||||||
|
|||||||
@@ -222,11 +222,6 @@
|
|||||||
<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"/>
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ public class AppPermission: BaseEntity
|
|||||||
default: return UnknownAppPermission(rawValue: self._permission)
|
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.
|
// Set by StoreApp.
|
||||||
@NSManaged public var appBundleID: String
|
@NSManaged public var appBundleID: String
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,70 @@
|
|||||||
|
//
|
||||||
|
// 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -15,6 +15,11 @@ 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
|
||||||
@@ -28,10 +33,15 @@ fileprivate extension NSManagedObject
|
|||||||
|
|
||||||
fileprivate extension NSManagedObject
|
fileprivate extension NSManagedObject
|
||||||
{
|
{
|
||||||
func setSourceSourceID(_ sourceID: String)
|
func setSourceId(_ 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)
|
||||||
{
|
{
|
||||||
@@ -52,6 +62,11 @@ 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)
|
||||||
{
|
{
|
||||||
@@ -61,6 +76,11 @@ 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
|
||||||
@@ -88,15 +108,28 @@ class Source11To17MigrationPolicy: NSEntityMigrationPolicy
|
|||||||
|
|
||||||
// Copied from Source.setSourceURL()
|
// Copied from Source.setSourceURL()
|
||||||
|
|
||||||
// sidestore official soruce has been moved to sidestore.io/apps-v2.json
|
// 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
|
// if we don't switch, users will end up with 2 offical sources
|
||||||
if sourceURL.absoluteString.contains("apps.sidestore.io") // if using old source
|
if let host = sourceURL.host,
|
||||||
|
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 ?? []
|
||||||
{
|
{
|
||||||
@@ -117,6 +150,9 @@ 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 ?? []
|
||||||
|
|||||||
@@ -106,9 +106,10 @@ 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!, into: context)
|
let releaseTrack = NSEntityDescription.insertNewObject(forEntityName: ReleaseTrack.entity().name! ?? ReleaseTrack.description(), 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
|
||||||
@@ -116,7 +117,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!, in: manager)
|
let appVersionMappingName = findEntityMappingName(for: AppVersion.entity().name ?? AppVersion.description(), 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()
|
||||||
@@ -145,5 +146,4 @@ 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))
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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?
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import UIKit
|
|||||||
|
|
||||||
public extension Source
|
public extension Source
|
||||||
{
|
{
|
||||||
static let altStoreIdentifier = try! Source.sourceID(from: Source.altStoreSourceURL)
|
static let altStoreIdentifier = "com.SideStore.SideStore"
|
||||||
|
|
||||||
#if STAGING
|
#if STAGING
|
||||||
|
|
||||||
@@ -280,6 +280,8 @@ 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?)
|
||||||
@@ -304,6 +306,9 @@ 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)
|
||||||
@@ -451,9 +456,10 @@ public extension Source
|
|||||||
{
|
{
|
||||||
func setSourceURL(_ sourceURL: URL) throws
|
func setSourceURL(_ sourceURL: URL) throws
|
||||||
{
|
{
|
||||||
let identifier = try Source.sourceID(from: sourceURL)
|
// commented out to retain source id as-is (independent of 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
|
||||||
|
|||||||
Reference in New Issue
Block a user