mirror of
https://github.com/SideStore/SideStore.git
synced 2026-02-09 06:43:25 +01:00
clean-checkpoint-1
This commit is contained in:
@@ -10,67 +10,6 @@ import CoreData
|
||||
import UIKit
|
||||
|
||||
import AltSign
|
||||
public extension ALTAppPermissionType
|
||||
{
|
||||
var localizedShortName: String? {
|
||||
switch self
|
||||
{
|
||||
case .photos: return NSLocalizedString("Photos", comment: "")
|
||||
case .backgroundAudio: return NSLocalizedString("Audio (BG)", comment: "")
|
||||
case .backgroundFetch: return NSLocalizedString("Fetch (BG)", comment: "")
|
||||
default: return nil
|
||||
}
|
||||
}
|
||||
|
||||
var localizedName: String? {
|
||||
switch self
|
||||
{
|
||||
case .photos: return NSLocalizedString("Photos", comment: "")
|
||||
case .camera: return NSLocalizedString("Camera", comment: "")
|
||||
case .location: return NSLocalizedString("Location", comment: "")
|
||||
case .contacts: return NSLocalizedString("Contacts", comment: "")
|
||||
case .reminders: return NSLocalizedString("Reminders", comment: "")
|
||||
case .appleMusic: return NSLocalizedString("Apple Music", comment: "")
|
||||
case .microphone: return NSLocalizedString("Microphone", comment: "")
|
||||
case .speechRecognition: return NSLocalizedString("Speech Recognition", comment: "")
|
||||
case .backgroundAudio: return NSLocalizedString("Background Audio", comment: "")
|
||||
case .backgroundFetch: return NSLocalizedString("Background Fetch", comment: "")
|
||||
case .bluetooth: return NSLocalizedString("Bluetooth", comment: "")
|
||||
case .network: return NSLocalizedString("Network", comment: "")
|
||||
case .calendars: return NSLocalizedString("Calendars", comment: "")
|
||||
case .touchID: return NSLocalizedString("Touch ID", comment: "")
|
||||
case .faceID: return NSLocalizedString("Face ID", comment: "")
|
||||
case .siri: return NSLocalizedString("Siri", comment: "")
|
||||
case .motion: return NSLocalizedString("Motion", comment: "")
|
||||
default: return nil
|
||||
}
|
||||
}
|
||||
|
||||
var icon: UIImage? {
|
||||
switch self
|
||||
{
|
||||
case .photos: return UIImage(systemName: "photo.on.rectangle.angled")
|
||||
case .camera: return UIImage(systemName: "camera.fill")
|
||||
case .location: return UIImage(systemName: "location.fill")
|
||||
case .contacts: return UIImage(systemName: "person.2.fill")
|
||||
case .reminders: return UIImage(systemName: "checklist")
|
||||
case .appleMusic: return UIImage(systemName: "music.note")
|
||||
case .microphone: return UIImage(systemName: "mic.fill")
|
||||
case .speechRecognition: return UIImage(systemName: "waveform.and.mic")
|
||||
case .backgroundAudio: return UIImage(systemName: "speaker.fill")
|
||||
case .backgroundFetch: return UIImage(systemName: "square.and.arrow.down")
|
||||
case .bluetooth: return UIImage(systemName: "wave.3.right")
|
||||
case .network: return UIImage(systemName: "network")
|
||||
case .calendars: return UIImage(systemName: "calendar")
|
||||
case .touchID: return UIImage(systemName: "touchid")
|
||||
case .faceID: return UIImage(systemName: "faceid")
|
||||
case .siri: return UIImage(systemName: "mic.and.signal.meter.fill")
|
||||
case .motion: return UIImage(systemName: "figure.walk.motion")
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@objc(AppPermission) @dynamicMemberLookup
|
||||
public class AppPermission: NSManagedObject, Fetchable
|
||||
|
||||
@@ -157,11 +157,15 @@ public extension AppVersion
|
||||
}
|
||||
|
||||
var isSupported: Bool {
|
||||
if let minOSVersion = self.minOSVersion, !ProcessInfo.processInfo.isOperatingSystemAtLeast(minOSVersion) {
|
||||
return false
|
||||
} else if let maxOSVersion = self.maxOSVersion, ProcessInfo.processInfo.operatingSystemVersion > maxOSVersion {
|
||||
if let minOSVersion = self.minOSVersion, !ProcessInfo.processInfo.isOperatingSystemAtLeast(minOSVersion)
|
||||
{
|
||||
return false
|
||||
}
|
||||
else if let maxOSVersion = self.maxOSVersion, ProcessInfo.processInfo.operatingSystemVersion > maxOSVersion
|
||||
{
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,6 +53,7 @@ public class DatabaseManager
|
||||
private let coordinatorQueue = OperationQueue()
|
||||
|
||||
private var ignoreWillMigrateDatabaseNotification = false
|
||||
|
||||
private init()
|
||||
{
|
||||
self.persistentContainer = PersistentContainer(name: "AltStore", bundle: Bundle(for: DatabaseManager.self))
|
||||
@@ -108,6 +109,7 @@ public extension DatabaseManager
|
||||
self.ignoreWillMigrateDatabaseNotification = true
|
||||
CFNotificationCenterPostNotification(CFNotificationCenterGetDarwinNotifyCenter(), .willMigrateDatabase, nil, nil, true)
|
||||
}
|
||||
|
||||
self.migrateDatabaseToAppGroupIfNeeded { (result) in
|
||||
switch result
|
||||
{
|
||||
|
||||
@@ -15,7 +15,7 @@ import SemanticVersion
|
||||
extension InstalledApp
|
||||
{
|
||||
public static var freeAccountActiveAppsLimit: Int {
|
||||
if UserDefaults.standard.ignoreActiveAppsLimit
|
||||
if UserDefaults.standard.isAppLimitDisabled
|
||||
{
|
||||
// MacDirtyCow exploit allows users to remove 3-app limit, so return 10 to match App ID limit per-week.
|
||||
// Don't return nil because that implies there is no limit, which isn't quite true due to App ID limit.
|
||||
@@ -159,15 +159,17 @@ public extension InstalledApp
|
||||
|
||||
func loadIcon(completion: @escaping (Result<UIImage?, Error>) -> Void)
|
||||
{
|
||||
if self.bundleIdentifier == StoreApp.altstoreAppID, let iconName = UIApplication.alt_shared?.alternateIconName
|
||||
{
|
||||
// Use alternate app icon for AltStore, if one is chosen.
|
||||
|
||||
let image = UIImage(named: iconName)
|
||||
completion(.success(image))
|
||||
|
||||
return
|
||||
}
|
||||
// TODO: @mahee96: Fix this later (reason: alternateIcon is not available for appEx)
|
||||
// if self.bundleIdentifier == StoreApp.altstoreAppID,
|
||||
// let iconName = UIApplication.alt_shared?.alternateIconName
|
||||
// {
|
||||
// // Use alternate app icon for AltStore, if one is chosen.
|
||||
//
|
||||
// let image = UIImage(named: iconName)
|
||||
// completion(.success(image))
|
||||
//
|
||||
// return
|
||||
// }
|
||||
|
||||
let hasAlternateIcon = self.hasAlternateIcon
|
||||
let alternateIconURL = self.alternateIconURL
|
||||
@@ -211,30 +213,34 @@ public extension InstalledApp
|
||||
{
|
||||
let fetchRequest = InstalledApp.fetchRequest() as NSFetchRequest<InstalledApp>
|
||||
|
||||
let predicateFormat = [
|
||||
// isActive && storeApp != nil && latestSupportedVersion != nil
|
||||
"%K == YES AND %K != nil AND %K != nil",
|
||||
// let predicateFormat = [
|
||||
// // isActive && storeApp != nil && latestSupportedVersion != nil
|
||||
// "%K == YES AND %K != nil AND %K != nil",
|
||||
|
||||
"AND",
|
||||
// "AND",
|
||||
|
||||
// latestSupportedVersion.version != installedApp.version || latestSupportedVersion.buildVersion != installedApp.storeBuildVersion
|
||||
//
|
||||
// We have to also check !(latestSupportedVersion.buildVersion == '' && installedApp.storeBuildVersion == nil)
|
||||
// because latestSupportedVersion.buildVersion stores an empty string for nil, while installedApp.storeBuildVersion uses NULL.
|
||||
"(%K != %K OR (%K != %K AND NOT (%K == '' AND %K == nil)))",
|
||||
// // latestSupportedVersion.version != installedApp.version || latestSupportedVersion.buildVersion != installedApp.storeBuildVersion
|
||||
// //
|
||||
// // We have to also check !(latestSupportedVersion.buildVersion == '' && installedApp.storeBuildVersion == nil)
|
||||
// // because latestSupportedVersion.buildVersion stores an empty string for nil, while installedApp.storeBuildVersion uses NULL.
|
||||
// "(%K != %K OR (%K != %K AND NOT (%K == '' AND %K == nil)))",
|
||||
|
||||
"AND",
|
||||
// "AND",
|
||||
|
||||
// !isPledgeRequired || isPledged
|
||||
"(%K == NO OR %K == YES)"
|
||||
].joined(separator: " ")
|
||||
// // !isPledgeRequired || isPledged
|
||||
// "(%K == NO OR %K == YES)"
|
||||
// ].joined(separator: " ")
|
||||
|
||||
fetchRequest.predicate = NSPredicate(format: predicateFormat,
|
||||
#keyPath(InstalledApp.isActive), #keyPath(InstalledApp.storeApp), #keyPath(InstalledApp.storeApp.latestSupportedVersion),
|
||||
#keyPath(InstalledApp.storeApp.latestSupportedVersion.version), #keyPath(InstalledApp.version),
|
||||
#keyPath(InstalledApp.storeApp.latestSupportedVersion._buildVersion), #keyPath(InstalledApp.storeBuildVersion),
|
||||
#keyPath(InstalledApp.storeApp.latestSupportedVersion._buildVersion), #keyPath(InstalledApp.storeBuildVersion),
|
||||
#keyPath(InstalledApp.storeApp.isPledgeRequired), #keyPath(InstalledApp.storeApp.isPledged))
|
||||
// fetchRequest.predicate = NSPredicate(format: predicateFormat,
|
||||
// #keyPath(InstalledApp.isActive), #keyPath(InstalledApp.storeApp), #keyPath(InstalledApp.storeApp.latestSupportedVersion),
|
||||
// #keyPath(InstalledApp.storeApp.latestSupportedVersion.version), #keyPath(InstalledApp.version),
|
||||
// #keyPath(InstalledApp.storeApp.latestSupportedVersion._buildVersion), #keyPath(InstalledApp.storeBuildVersion),
|
||||
// #keyPath(InstalledApp.storeApp.latestSupportedVersion._buildVersion), #keyPath(InstalledApp.storeBuildVersion),
|
||||
// #keyPath(InstalledApp.storeApp.isPledgeRequired), #keyPath(InstalledApp.storeApp.isPledged))
|
||||
|
||||
fetchRequest.predicate = NSPredicate(format: "%K == YES AND %K == YES",
|
||||
#keyPath(InstalledApp.isActive), #keyPath(InstalledApp.hasUpdate))
|
||||
|
||||
return fetchRequest
|
||||
}
|
||||
|
||||
|
||||
@@ -356,11 +356,11 @@ open class MergePolicy: RSTRelationshipPreservingMergePolicy
|
||||
// Screenshots
|
||||
if let sortedScreenshotIDs = sortedScreenshotIDsByGlobalAppID[globallyUniqueID],
|
||||
let sortedScreenshotIDsArray = sortedScreenshotIDs.array as? [String],
|
||||
case let databaseScreenshotIDs = databaseObject.allScreenshots.map({ $0.screenshotID }),
|
||||
case let databaseScreenshotIDs = databaseObject.screenshots.map({ $0.screenshotID }),
|
||||
databaseScreenshotIDs != sortedScreenshotIDsArray
|
||||
{
|
||||
// Screenshot order is incorrect, so attempt to fix by re-sorting.
|
||||
let fixedScreenshots = databaseObject.allScreenshots.sorted { (screenshotA, screenshotB) in
|
||||
let fixedScreenshots = databaseObject.screenshots.sorted { (screenshotA, screenshotB) in
|
||||
let indexA = sortedScreenshotIDs.index(of: screenshotA.screenshotID)
|
||||
let indexB = sortedScreenshotIDs.index(of: screenshotB.screenshotID)
|
||||
return indexA < indexB
|
||||
|
||||
@@ -45,7 +45,8 @@ public class PatreonAccount: NSManagedObject, Fetchable
|
||||
// {
|
||||
// self.isPatron = false
|
||||
// }
|
||||
self.isPatron = true
|
||||
// self.isPatron = true
|
||||
self.isAltStorePatron = true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -462,7 +462,7 @@ public extension Source
|
||||
let source = Source(context: context)
|
||||
source.name = "SideStore Offical"
|
||||
source.identifier = Source.altStoreIdentifier
|
||||
source.sourceURL = Source.altStoreSourceURL
|
||||
try! source.setSourceURL(Source.altStoreSourceURL)
|
||||
|
||||
return source
|
||||
}
|
||||
|
||||
@@ -190,7 +190,7 @@ public class StoreApp: NSManagedObject, Decodable, Fetchable
|
||||
permission.sourceID = self.sourceIdentifier ?? ""
|
||||
}
|
||||
|
||||
for screenshot in self.allScreenshots
|
||||
for screenshot in self.screenshots
|
||||
{
|
||||
screenshot.sourceID = self.sourceIdentifier ?? ""
|
||||
}
|
||||
@@ -282,8 +282,6 @@ public class StoreApp: NSManagedObject, Decodable, Fetchable
|
||||
case developerName
|
||||
case localizedDescription
|
||||
case iconURL
|
||||
case screenshotURLs
|
||||
case downloadURL
|
||||
case platformURLs
|
||||
case screenshots
|
||||
case tintColor
|
||||
@@ -606,7 +604,7 @@ public extension StoreApp
|
||||
func screenshots(for deviceType: ALTDeviceType) -> [AppScreenshot]
|
||||
{
|
||||
//TODO: Support multiple device types
|
||||
let filteredScreenshots = self.allScreenshots.filter { $0.deviceType == deviceType }
|
||||
let filteredScreenshots = self.screenshots.filter { $0.deviceType == deviceType }
|
||||
return filteredScreenshots
|
||||
}
|
||||
|
||||
@@ -626,7 +624,7 @@ public extension StoreApp
|
||||
let preferredScreenshots = self.screenshots(for: deviceType)
|
||||
guard !preferredScreenshots.isEmpty else {
|
||||
// There are no screenshots for deviceType, so return _all_ screenshots instead.
|
||||
return self.allScreenshots
|
||||
return self.screenshots
|
||||
}
|
||||
|
||||
return preferredScreenshots
|
||||
|
||||
Reference in New Issue
Block a user