From 9ddc27f6ca224a43b889e250b8e69fab102ddd0a Mon Sep 17 00:00:00 2001 From: Riley Testut Date: Wed, 11 Oct 2023 17:59:01 -0500 Subject: [PATCH] [AltStoreCore] Updates DatabaseManager to support #Preview macro Synchronously loads database via startForPreview(), and also erases database for DEBUG builds. --- AltStore.xcodeproj/project.pbxproj | 4 +++ .../Extensions/ProcessInfo+Previews.swift | 16 +++++++++ AltStoreCore/Model/DatabaseManager.swift | 36 +++++++++++++++++-- 3 files changed, 54 insertions(+), 2 deletions(-) create mode 100644 AltStoreCore/Extensions/ProcessInfo+Previews.swift diff --git a/AltStore.xcodeproj/project.pbxproj b/AltStore.xcodeproj/project.pbxproj index d3f30f18..bc1f7738 100644 --- a/AltStore.xcodeproj/project.pbxproj +++ b/AltStore.xcodeproj/project.pbxproj @@ -413,6 +413,7 @@ D5A299882AAB9E4E00A3988D /* JITError.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5A1D2E32AA50EB60066CACC /* JITError.swift */; }; D5A299892AAB9E5900A3988D /* AppProcess.swift in Sources */ = {isa = PBXBuildFile; fileRef = D59A6B7D2AA9226C00F61259 /* AppProcess.swift */; }; D5ACE84528E3B8450021CAB9 /* ClearAppCacheOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5ACE84428E3B8450021CAB9 /* ClearAppCacheOperation.swift */; }; + D5B6F6A92AD75D01007EED5A /* ProcessInfo+Previews.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5B6F6A82AD75D01007EED5A /* ProcessInfo+Previews.swift */; }; D5BA9E9B2A9FE1E8007C0661 /* JITManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5BA9E9A2A9FE1E8007C0661 /* JITManager.swift */; }; D5C8ACDB2A956B2B00669F92 /* Process+STPrivilegedTask.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5C8ACDA2A956B2B00669F92 /* Process+STPrivilegedTask.swift */; }; D5CA0C4B280E141900469595 /* ManagedPatron.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5CA0C4A280E141900469595 /* ManagedPatron.swift */; }; @@ -1068,6 +1069,7 @@ D5A1D2EA2AA513410066CACC /* URL+Tools.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "URL+Tools.swift"; sourceTree = ""; }; D5A2193329B14F94002229FC /* DeprecatedAPIs.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeprecatedAPIs.swift; sourceTree = ""; }; D5ACE84428E3B8450021CAB9 /* ClearAppCacheOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClearAppCacheOperation.swift; sourceTree = ""; }; + D5B6F6A82AD75D01007EED5A /* ProcessInfo+Previews.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ProcessInfo+Previews.swift"; sourceTree = ""; }; D5BA9E9A2A9FE1E8007C0661 /* JITManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JITManager.swift; sourceTree = ""; }; D5C8ACDA2A956B2B00669F92 /* Process+STPrivilegedTask.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Process+STPrivilegedTask.swift"; sourceTree = ""; }; D5CA0C4A280E141900469595 /* ManagedPatron.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ManagedPatron.swift; sourceTree = ""; }; @@ -1726,6 +1728,7 @@ D5F48B4729CCF21B002B52A4 /* AltStore+Async.swift */, D5893F7E2A14183200E767CD /* NSManagedObjectContext+Conveniences.swift */, D52A2F962ACB40F700BDF8E3 /* Logger+AltStore.swift */, + D5B6F6A82AD75D01007EED5A /* ProcessInfo+Previews.swift */, ); path = Extensions; sourceTree = ""; @@ -3063,6 +3066,7 @@ BFAECC5A2501B0A400528F27 /* NetworkConnection.swift in Sources */, D5F99A1828D11DB500476A16 /* AltStore10ToAltStore11.xcmappingmodel in Sources */, BF66EEE92501AED0007EE018 /* JSONDecoder+Properties.swift in Sources */, + D5B6F6A92AD75D01007EED5A /* ProcessInfo+Previews.swift in Sources */, BF66EEEB2501AED0007EE018 /* UIApplication+AppExtension.swift in Sources */, D5F48B4829CCF21B002B52A4 /* AltStore+Async.swift in Sources */, BF66EED92501AECA007EE018 /* Team.swift in Sources */, diff --git a/AltStoreCore/Extensions/ProcessInfo+Previews.swift b/AltStoreCore/Extensions/ProcessInfo+Previews.swift new file mode 100644 index 00000000..2687054d --- /dev/null +++ b/AltStoreCore/Extensions/ProcessInfo+Previews.swift @@ -0,0 +1,16 @@ +// +// ProcessInfo+Previews.swift +// AltStoreCore +// +// Created by Riley Testut on 10/11/23. +// Copyright © 2023 Riley Testut. All rights reserved. +// + +import Foundation + +public extension ProcessInfo +{ + var isPreview: Bool { + ProcessInfo.processInfo.environment["XCODE_RUNNING_FOR_PREVIEWS"] == "1" + } +} diff --git a/AltStoreCore/Model/DatabaseManager.swift b/AltStoreCore/Model/DatabaseManager.swift index 6ec9a7f2..b147ea30 100644 --- a/AltStoreCore/Model/DatabaseManager.swift +++ b/AltStoreCore/Model/DatabaseManager.swift @@ -86,8 +86,24 @@ public extension DatabaseManager guard !self.isStarted else { return finish(nil) } - if self.persistentContainer.isMigrationRequired { - + #if DEBUG + // Wrap in #if DEBUG to *ensure* we never accidentally delete production databases. + if ProcessInfo.processInfo.isPreview + { + do + { + print("!!! Purging database for preview...") + try FileManager.default.removeItem(at: PersistentContainer.defaultDirectoryURL()) + } + catch + { + print("Failed to remove database directory for preview.", error) + } + } + #endif + + if self.persistentContainer.isMigrationRequired + { // Quit any other running AltStore processes to prevent concurrent database access during and after migration. self.ignoreWillMigrateDatabaseNotification = true CFNotificationCenterPostNotification(CFNotificationCenterGetDarwinNotifyCenter(), .willMigrateDatabase, nil, nil, true) @@ -164,6 +180,22 @@ public extension DatabaseManager } } +public extension DatabaseManager +{ + func startForPreview() + { + let semaphore = DispatchSemaphore(value: 0) + + self.dispatchQueue.async { + self.startCompletionHandlers.append { error in + semaphore.signal() + } + } + + semaphore.wait() + } +} + public extension DatabaseManager { var viewContext: NSManagedObjectContext {