Browse Source

show directory picker if no backup is present in the Delta Chat Document folder

cyberta 2 years ago
parent
commit
99e9a33416

+ 50 - 13
deltachat-ios/Controller/WelcomeViewController.swift

@@ -8,6 +8,7 @@ class WelcomeViewController: UIViewController, ProgressAlertHandler {
     private var backupProgressObserver: NSObjectProtocol?
     var progressObserver: NSObjectProtocol?
     var onProgressSuccess: VoidFunction?
+    private var securityScopedResource: NSURL?
 
     private lazy var scrollView: UIScrollView = {
         let scrollView = UIScrollView()
@@ -58,6 +59,12 @@ class WelcomeViewController: UIViewController, ProgressAlertHandler {
                                action: #selector(moreButtonPressed))
     }()
 
+    private lazy var mediaPicker: MediaPicker? = {
+        let mediaPicker = MediaPicker(navigationController: navigationController)
+        mediaPicker.delegate = self
+        return mediaPicker
+    }()
+
     private var qrCodeReader: QrCodeReaderController?
     weak var progressAlert: UIAlertController?
 
@@ -267,23 +274,20 @@ class WelcomeViewController: UIViewController, ProgressAlertHandler {
         addProgressHudBackupListener()
 
         if let documentsDirectory = ensureDcDocFolderExists(),
-           let file = dcContext.imexHasBackup(filePath: documentsDirectory.relativePath) {
-            logger.info("restoring backup: \(file)")
-            showProgressAlert(title: String.localized("import_backup_title"), dcContext: dcContext)
-            dcAccounts.stopIo()
-            dcContext.imex(what: DC_IMEX_IMPORT_BACKUP, directory: file)
+           let filePath = dcContext.imexHasBackup(filePath: documentsDirectory.relativePath) {
+            importBackup(at: filePath)
         } else {
-            let alert = UIAlertController(
-                title: String.localized("import_backup_title"),
-                message: String.localizedStringWithFormat(
-                    String.localized("import_backup_no_backup_found"),
-                    "➔ Mac-Finder or iTunes ➔ iPhone ➔ " + String.localized("files") + " ➔ Delta Chat"), // iTunes was used up to Maverick 10.4
-                preferredStyle: .alert)
-            alert.addAction(UIAlertAction(title: String.localized("ok"), style: .cancel))
-            present(alert, animated: true)
+            mediaPicker?.showDocumentLibrary(selectFolder: true)
         }
     }
 
+    private func importBackup(at filepath: String) {
+        logger.info("restoring backup: \(filepath)")
+        showProgressAlert(title: String.localized("import_backup_title"), dcContext: dcContext)
+        dcAccounts.stopIo()
+        dcContext.imex(what: DC_IMEX_IMPORT_BACKUP, directory: filepath)
+    }
+
     private func ensureDcDocFolderExists() -> URL? {
         let fileManager = FileManager.default
         guard let documentsDirectory = try? fileManager.url(for: .documentDirectory,
@@ -309,9 +313,13 @@ class WelcomeViewController: UIViewController, ProgressAlertHandler {
                 if let error = ui["error"] as? Bool, error {
                     self.dcAccounts.startIo()
                     self.updateProgressAlert(error: ui["errorMessage"] as? String)
+                    self.securityScopedResource?.stopAccessingSecurityScopedResource()
+                    self.securityScopedResource = nil
                 } else if let done = ui["done"] as? Bool, done {
                     self.dcAccounts.startIo()
                     self.updateProgressAlertSuccess(completion: self.handleBackupRestoreSuccess)
+                    self.securityScopedResource?.stopAccessingSecurityScopedResource()
+                    self.securityScopedResource = nil
                 } else {
                     self.updateProgressAlertValue(value: ui["progress"] as? Int)
                 }
@@ -568,3 +576,32 @@ class WelcomeContentView: UIView {
          onImportBackup?()
      }
 }
+
+extension WelcomeViewController: MediaPickerDelegate {
+    func onDocumentSelected(url: NSURL) {
+        logger.debug("onDocumentsSelected: \(String(describing: url.relativePath))")
+        // ensure we can access folders outside of the app's sandbox
+        let shouldStopAccessing = url.startAccessingSecurityScopedResource()
+        if shouldStopAccessing {
+            securityScopedResource = url
+        }
+
+        if let path = url.relativePath, let filePath = dcContext.imexHasBackup(filePath: path) {
+            importBackup(at: filePath)
+        } else {
+            onSelectionCancelled()
+            securityScopedResource = nil
+        }
+    }
+
+    func onSelectionCancelled() {
+        let alert = UIAlertController(
+            title: String.localized("import_backup_title"),
+            message: String.localizedStringWithFormat(
+                String.localized("import_backup_no_backup_found"),
+                "➔ Mac-Finder or iTunes ➔ iPhone ➔ " + String.localized("files") + " ➔ Delta Chat"), // iTunes was used up to Maverick 10.4
+            preferredStyle: .alert)
+        alert.addAction(UIAlertAction(title: String.localized("ok"), style: .cancel))
+        present(alert, animated: true)
+    }
+}

+ 25 - 7
deltachat-ios/Helper/MediaPicker.swift

@@ -9,9 +9,13 @@ protocol MediaPickerDelegate: class {
     func onVoiceMessageRecorded(url: NSURL)
     func onVoiceMessageRecorderClosed()
     func onDocumentSelected(url: NSURL)
+    func onSelectionCancelled()
 }
 
 extension MediaPickerDelegate {
+    func onImageSelected(image: UIImage) {
+        logger.debug("image selected")
+    }
     func onImageSelected(url: NSURL) {
         logger.debug("image selected: ", url.path ?? "unknown")
     }
@@ -27,6 +31,9 @@ extension MediaPickerDelegate {
     func onDocumentSelected(url: NSURL) {
         logger.debug("document selected: \(url)")
     }
+    func onSelectionCancelled() {
+        logger.debug("media selection cancelled")
+    }
 }
 
 class MediaPicker: NSObject, UINavigationControllerDelegate {
@@ -75,15 +82,22 @@ class MediaPicker: NSObject, UINavigationControllerDelegate {
         }
     }
 
-    func showDocumentLibrary() {
-        // TODO: instead of adding kUTTypeData, we probably should implement a Document provider for webxdc's https://developer.apple.com/library/archive/documentation/General/Conceptual/ExtensibilityPG/FileProvider.html#//apple_ref/doc/uid/TP40014214-CH18
+    func showDocumentLibrary(selectFolder: Bool = false) {
         let documentPicker: UIDocumentPickerViewController
-        if #available(iOS 15.0, *) {
-            let types = [UTType.pdf, UTType.text, UTType.rtf, UTType.spreadsheet, UTType.vCard, UTType.zip, UTType.image, UTType.data]
-            documentPicker = UIDocumentPickerViewController(forOpeningContentTypes: types, asCopy: true)
+        if selectFolder {
+            if #available(iOS 15.0, *) {
+                documentPicker = UIDocumentPickerViewController(forOpeningContentTypes: [UTType.folder], asCopy: false)
+            } else {
+                documentPicker = UIDocumentPickerViewController(documentTypes: [kUTTypeFolder] as [String], in: .open)
+            }
         } else {
-            let types = [kUTTypePDF, kUTTypeText, kUTTypeRTF, kUTTypeSpreadsheet, kUTTypeVCard, kUTTypeZipArchive, kUTTypeImage, kUTTypeData]
-            documentPicker = UIDocumentPickerViewController(documentTypes: types as [String], in: .import)
+            if #available(iOS 15.0, *) {
+                let types = [UTType.pdf, UTType.text, UTType.rtf, UTType.spreadsheet, UTType.vCard, UTType.zip, UTType.image, UTType.data]
+                documentPicker = UIDocumentPickerViewController(forOpeningContentTypes: types, asCopy: true)
+            } else {
+                let types = [kUTTypePDF, kUTTypeText, kUTTypeRTF, kUTTypeSpreadsheet, kUTTypeVCard, kUTTypeZipArchive, kUTTypeImage, kUTTypeData]
+                documentPicker = UIDocumentPickerViewController(documentTypes: types as [String], in: .import)
+            }
         }
         documentPicker.delegate = self
         documentPicker.allowsMultipleSelection = false
@@ -211,4 +225,8 @@ extension MediaPicker: UIDocumentPickerDelegate {
         let url = urls[0] as NSURL
         self.delegate?.onDocumentSelected(url: url)
     }
+
+    func documentPickerWasCancelled(_ controller: UIDocumentPickerViewController) {
+        self.delegate?.onSelectionCancelled()
+    }
 }