import SwiftUI import UniformTypeIdentifiers struct SettingsSectionImportExportView: View { @EnvironmentObject private var settings: SettingsManager @State private var isFileExporterPresented = false @State private var isFileImporterPresented = false @State private var bookmarksExportDocument: JSONFileDocument? @State private var bookmarksExportFilename = "sora_bookmarks.json" @State private var exportError: Error? @State private var importError: Error? private let dateFormatter: DateFormatter = { let formatter = DateFormatter() formatter.dateFormat = "yyyy-MM-dd_HH-mm-ss" return formatter }() var body: some View { Group { Button("Import Bookmarks") { isFileImporterPresented = true } Button("Export Bookmarks") { prepareBookmarksExport() } } #if os(macOS) .trailingFrame() #endif .fileExporter( isPresented: $isFileExporterPresented, document: bookmarksExportDocument, contentType: .json, defaultFilename: bookmarksExportFilename ) { result in bookmarksExportDocument = nil switch result { case .success: break case .failure(let error): if !isUserCancelled(error) { exportError = error } } } .fileImporter( isPresented: $isFileImporterPresented, allowedContentTypes: [.json], allowsMultipleSelection: false ) { result in handleImportResult(result) } .alert( "Export Failed", isPresented: Binding( get: { exportError != nil }, set: { if !$0 { exportError = nil } } ) ) { Button("OK", role: .cancel) { () } } message: { Text(exportError?.localizedDescription ?? "An unknown error occurred while exporting.") } .alert( "Import Failed", isPresented: Binding( get: { importError != nil }, set: { if !$0 { importError = nil } } ) ) { Button("OK", role: .cancel) { () } } message: { Text(importError?.localizedDescription ?? "An unknown error occurred while importing.") } } private func prepareBookmarksExport() { do { let data = try settings.exportBookmarks() let timestamp = dateFormatter.string(from: Date()) bookmarksExportDocument = JSONFileDocument(data) bookmarksExportFilename = "sora_bookmarks_\(timestamp).json" isFileExporterPresented = true } catch { exportError = error } } private func handleImportResult(_ result: Result<[URL], Error>) { do { guard let selectedFile = try result.get().first else { return } guard selectedFile.startAccessingSecurityScopedResource() else { throw ImportError.accessDenied } defer { selectedFile.stopAccessingSecurityScopedResource() } let data = try Data(contentsOf: selectedFile) try settings.importBookmarks(from: data) } catch { importError = error } } private func isUserCancelled(_ error: Error) -> Bool { let error = error as NSError return error.domain == NSCocoaErrorDomain && error.code == CocoaError.userCancelled.rawValue } private enum ImportError: Error { case accessDenied } }