mirror of
https://github.com/SideStore/SideStore.git
synced 2026-02-09 06:43:25 +01:00
[Feature]: Import external backup, Restore n-1 backup if current backup is corrupted by importing wrong directory
This commit is contained in:
@@ -1357,6 +1357,50 @@ private extension MyAppsViewController
|
||||
self.present(alertController, animated: true, completion: nil)
|
||||
}
|
||||
|
||||
func importBackup(for installedApp: InstalledApp){
|
||||
ImportExport.importBackup(presentingViewController: self, for: installedApp) { result in
|
||||
var toast: ToastView
|
||||
switch(result){
|
||||
case .failure(let error):
|
||||
toast = ToastView(error: error, opensLog: false)
|
||||
break
|
||||
case .success:
|
||||
toast = ToastView(text: "Import Backup successful for \(installedApp.name)",
|
||||
detailText: "Use 'Restore Backup' option to restore data from this imported backup")
|
||||
}
|
||||
DispatchQueue.main.async {
|
||||
toast.show(in: self)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func getPreviousBackupURL(_ installedApp: InstalledApp) -> URL
|
||||
{
|
||||
let backupURL = FileManager.default.backupDirectoryURL(for: installedApp)!
|
||||
let backupBakURL = ImportExport.getPreviousBackupURL(backupURL)
|
||||
return backupBakURL
|
||||
}
|
||||
|
||||
func restorePreviousBackup(for installedApp: InstalledApp){
|
||||
let backupURL = FileManager.default.backupDirectoryURL(for: installedApp)!
|
||||
let backupBakURL = ImportExport.getPreviousBackupURL(backupURL)
|
||||
|
||||
// backupBakURL is expected to exist at this point, this needs to be ensured by caller logic
|
||||
// or invoke this action only when backupBakURL exists
|
||||
|
||||
// delete the current backup
|
||||
if(FileManager.default.fileExists(atPath: backupURL.path)){
|
||||
try! FileManager.default.removeItem(at: backupURL)
|
||||
}
|
||||
|
||||
// restore the previously saved backup as current backup
|
||||
// (don't delete the N-1 backup yet so copy instead of move)
|
||||
try! FileManager.default.copyItem(at: backupBakURL, to: backupURL)
|
||||
|
||||
//perform restore of data from the backup
|
||||
restore(installedApp)
|
||||
}
|
||||
|
||||
func restore(_ installedApp: InstalledApp)
|
||||
{
|
||||
guard minimuxerStatus else { return }
|
||||
@@ -1810,9 +1854,17 @@ extension MyAppsViewController
|
||||
self.exportBackup(for: installedApp)
|
||||
}
|
||||
|
||||
let restoreBackupAction = UIAction(title: NSLocalizedString("Restore Backup", comment: ""), image: UIImage(systemName: "arrow.down.doc")) { (action) in
|
||||
let importBackupAction = UIAction(title: NSLocalizedString("Import Backup", comment: ""), image: UIImage(systemName: "arrow.down.doc")) { (action) in
|
||||
self.importBackup(for: installedApp)
|
||||
}
|
||||
|
||||
let restoreBackupAction = UIAction(title: NSLocalizedString("Restore Backup", comment: "Restores the last or current backup of this app"), image: UIImage(systemName: "arrow.down.doc")) { (action) in
|
||||
self.restore(installedApp)
|
||||
}
|
||||
|
||||
let restorePreviousBackupAction = UIAction(title: NSLocalizedString("Restore Previous Backup", comment: "Restores the backup saved before the current backup was created."), image: UIImage(systemName: "arrow.down.doc")) { (action) in
|
||||
self.restorePreviousBackup(for: installedApp)
|
||||
}
|
||||
|
||||
let chooseIconAction = UIAction(title: NSLocalizedString("Photos", comment: ""), image: UIImage(systemName: "photo")) { (action) in
|
||||
self.chooseIcon(for: installedApp)
|
||||
@@ -1878,11 +1930,11 @@ extension MyAppsViewController
|
||||
var outError: NSError? = nil
|
||||
|
||||
self.coordinator.coordinate(readingItemAt: backupDirectoryURL, options: [.withoutChanges], error: &outError) { (backupDirectoryURL) in
|
||||
#if DEBUG
|
||||
backupExists = true
|
||||
#else
|
||||
// #if DEBUG
|
||||
// backupExists = true
|
||||
// #else
|
||||
backupExists = FileManager.default.fileExists(atPath: backupDirectoryURL.path)
|
||||
#endif
|
||||
// #endif
|
||||
}
|
||||
|
||||
if backupExists
|
||||
@@ -1903,16 +1955,23 @@ extension MyAppsViewController
|
||||
if installedApp.isActive
|
||||
{
|
||||
actions.append(deactivateAction)
|
||||
// import backup into shared backups dir is allowed
|
||||
actions.append(importBackupAction)
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
|
||||
if installedApp.bundleIdentifier != StoreApp.altstoreAppID
|
||||
{
|
||||
actions.append(removeAction)
|
||||
// have an option to restore the n-1 backup
|
||||
if FileManager.default.fileExists(atPath: getPreviousBackupURL(installedApp).path){
|
||||
actions.append(restorePreviousBackupAction)
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
// #if DEBUG
|
||||
// if installedApp.bundleIdentifier != StoreApp.altstoreAppID
|
||||
// {
|
||||
// actions.append(removeAction)
|
||||
// }
|
||||
//
|
||||
// #else
|
||||
|
||||
if (UserDefaults.standard.legacySideloadedApps ?? []).contains(installedApp.bundleIdentifier)
|
||||
{
|
||||
@@ -1926,9 +1985,29 @@ extension MyAppsViewController
|
||||
actions.append(removeAction)
|
||||
}
|
||||
|
||||
#endif
|
||||
// #endif
|
||||
}
|
||||
|
||||
// Change the order of entries to make changes to how the context menu is displayed
|
||||
let orderedActions = [
|
||||
openMenu,
|
||||
refreshAction,
|
||||
activateAction,
|
||||
jitAction,
|
||||
changeIconMenu,
|
||||
backupAction,
|
||||
exportBackupAction,
|
||||
importBackupAction,
|
||||
restoreBackupAction,
|
||||
restorePreviousBackupAction,
|
||||
deactivateAction,
|
||||
removeAction,
|
||||
]
|
||||
|
||||
// remove non-selected actions from the all-actions ordered list
|
||||
// this way the declaration of the action in the above code doesn't determine the context menu order
|
||||
actions = orderedActions.filter{ action in actions.contains(action)}
|
||||
|
||||
var title: String?
|
||||
|
||||
if let storeApp = installedApp.storeApp, storeApp.isPledgeRequired, !storeApp.isPledged
|
||||
|
||||
Reference in New Issue
Block a user