diff --git a/Passepartout/Sources/AppConstants.swift b/Passepartout/Sources/AppConstants.swift index d7170a7b..28d392f7 100644 --- a/Passepartout/Sources/AppConstants.swift +++ b/Passepartout/Sources/AppConstants.swift @@ -97,7 +97,7 @@ class AppConstants { private static let fileName = "Debug.log" static var fileURL: URL { - return FileManager.default.userURL(for: .cachesDirectory, appending: fileName) + return GroupConstants.App.cachesURL.appendingPathComponent(fileName) } private static let console: ConsoleDestination = { diff --git a/Passepartout/Sources/GroupConstants.swift b/Passepartout/Sources/GroupConstants.swift index c2adb9e7..b52bd0a3 100644 --- a/Passepartout/Sources/GroupConstants.swift +++ b/Passepartout/Sources/GroupConstants.swift @@ -53,6 +53,25 @@ class GroupConstants { static let tunnelIdentifier = "com.algoritmico.macos.Passepartout.Tunnel" #endif + + private static var containerURL: URL { + guard let url = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: appGroup) else { + fatalError("Unable to access App Group container") + } + return url + } + + static let documentsURL: URL = { + let url = containerURL.appendingPathComponent("Documents", isDirectory: true) + try? FileManager.default.createDirectory(at: url, withIntermediateDirectories: true, attributes: nil) + return url + }() + + static let cachesURL: URL = { + let url = containerURL.appendingPathComponent("Library/Caches", isDirectory: true) + try? FileManager.default.createDirectory(at: url, withIntermediateDirectories: true, attributes: nil) + return url + }() } class VPN { diff --git a/Passepartout/Sources/Model/ConnectionService.swift b/Passepartout/Sources/Model/ConnectionService.swift index 7d0c3bc1..524260e4 100644 --- a/Passepartout/Sources/Model/ConnectionService.swift +++ b/Passepartout/Sources/Model/ConnectionService.swift @@ -58,7 +58,11 @@ class ConnectionService: Codable { var directory: String? = nil var rootURL: URL { - return FileManager.default.userURL(for: .documentDirectory, appending: directory) + var url = GroupConstants.App.documentsURL + if let directory = directory { + url.appendPathComponent(directory) + } + return url } private var providersURL: URL { diff --git a/Passepartout/Sources/Model/TransientStore.swift b/Passepartout/Sources/Model/TransientStore.swift index 0574e550..389958af 100644 --- a/Passepartout/Sources/Model/TransientStore.swift +++ b/Passepartout/Sources/Model/TransientStore.swift @@ -36,7 +36,7 @@ class TransientStore { static let shared = TransientStore() private static var serviceURL: URL { - return FileManager.default.userURL(for: .documentDirectory, appending: AppConstants.Store.serviceFilename) + return GroupConstants.App.documentsURL.appendingPathComponent(AppConstants.Store.serviceFilename) } let service: ConnectionService @@ -51,6 +51,7 @@ class TransientStore { } private init() { + TransientStore.migrateDocumentsToAppGroup() // this must be graceful ConnectionService.migrateJSON(from: TransientStore.serviceURL, to: TransientStore.serviceURL) @@ -85,4 +86,35 @@ class TransientStore { service.saveProfiles() } } + + // + + private static func migrateDocumentsToAppGroup() { + var hasMigrated = false + let oldDocumentsURL = FileManager.default.userURL(for: .documentDirectory, appending: nil) + let newDocumentsURL = GroupConstants.App.documentsURL + log.debug("App documentsURL: \(oldDocumentsURL)") + log.debug("Group documentsURL: \(newDocumentsURL)") + let fm = FileManager.default + do { + for c in try fm.contentsOfDirectory(atPath: oldDocumentsURL.path) { + guard c != "Inbox" else { + continue + } + let old = oldDocumentsURL.appendingPathComponent(c) + let new = newDocumentsURL.appendingPathComponent(c) + log.verbose("Move:") + log.verbose("\tFROM: \(old)") + log.verbose("\tTO: \(new)") + try fm.moveItem(at: old, to: new) + hasMigrated = true + } + } catch let e { + hasMigrated = false + log.error("Could not migrate documents to App Group: \(e)") + } + if hasMigrated { + log.debug("Documents migrated to App Group") + } + } } diff --git a/Passepartout/Sources/Services/InfrastructureFactory.swift b/Passepartout/Sources/Services/InfrastructureFactory.swift index 87fda866..eb84655a 100644 --- a/Passepartout/Sources/Services/InfrastructureFactory.swift +++ b/Passepartout/Sources/Services/InfrastructureFactory.swift @@ -75,7 +75,7 @@ class InfrastructureFactory { } self.bundle = bundle - cachePath = FileManager.default.userURL(for: .cachesDirectory, appending: nil) + cachePath = GroupConstants.App.cachesURL cache = [:] lastUpdate = [:] }