You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

51 lines
1.9 KiB

import Foundation
/// Quell- und Zielordner, persistiert über Security-Scoped Bookmarks statt
/// roher Pfade — überlebt damit auch einen späteren Wechsel in den App
/// Sandbox (README: "@AppStorage + Security-Scoped Bookmarks").
@MainActor
final class AppSettings: ObservableObject {
@Published private(set) var sourceFolder: URL?
@Published private(set) var targetFolder: URL?
private enum DefaultsKey {
static let sourceBookmark = "dev.zielke.droptwo.sourceFolderBookmark"
static let targetBookmark = "dev.zielke.droptwo.targetFolderBookmark"
}
init() {
sourceFolder = Self.resolveBookmark(forKey: DefaultsKey.sourceBookmark)
targetFolder = Self.resolveBookmark(forKey: DefaultsKey.targetBookmark)
}
func setSourceFolder(_ url: URL) {
sourceFolder = url
Self.storeBookmark(for: url, key: DefaultsKey.sourceBookmark)
}
func setTargetFolder(_ url: URL) {
targetFolder = url
Self.storeBookmark(for: url, key: DefaultsKey.targetBookmark)
}
private static func storeBookmark(for url: URL, key: String) {
do {
let data = try url.bookmarkData(options: .withSecurityScope, includingResourceValuesForKeys: nil, relativeTo: nil)
UserDefaults.standard.set(data, forKey: key)
} catch {
// Best effort: der Ordner bleibt für die laufende Sitzung trotzdem
// gesetzt, nur der Neustart-Fall geht dann verloren.
}
}
private static func resolveBookmark(forKey key: String) -> URL? {
guard let data = UserDefaults.standard.data(forKey: key) else { return nil }
var isStale = false
guard let url = try? URL(resolvingBookmarkData: data, options: .withSecurityScope, relativeTo: nil, bookmarkDataIsStale: &isStale) else {
return nil
}
_ = url.startAccessingSecurityScopedResource()
return url
}
}

Powered by TurnKey Linux.