Sets up app-level commands (About, Check for Updates)
FiaxeApp.swift
Copy
Ask AI
@mainstruct R2VaultApp: App { @NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate @State private var viewModel: AppViewModel @State private var menuBarManager: MenuBarManager init() { let vm = AppViewModel() _viewModel = State(initialValue: vm) _menuBarManager = State(initialValue: MenuBarManager(viewModel: vm)) } var body: some Scene { WindowGroup(id: "main") { ContentView() .environment(viewModel) } .defaultSize(width: 800, height: 560) .windowResizability(.contentMinSize) Settings { SettingsView() .environment(viewModel) } }}
Menu bar-only app: The AppDelegate prevents the app from quitting when the window closes, and LSUIElement = YES in Info.plist keeps it out of the Dock.
struct R2Object: Identifiable, Sendable { let id: UUID let key: String // Full path: "photos/vacation/image.jpg" let size: Int64 // Bytes let lastModified: Date? let isFolder: Bool var name: String { // Extract filename/folder name from key let components = key.split(separator: "/") return String(components.last ?? "") }}
@Observablefinal class FileUploadTask: Identifiable { let id: UUID let fileName: String let fileSize: Int64 let fileURL: URL var progress: Double = 0 var status: Status = .pending var errorMessage: String? var resultURL: URL? var uploadKey: String? // Target R2 key var parentFolderBookmark: Data? // Security-scoped bookmark var fileBookmark: Data? var uploadTask: Task<Void, Never>? // For cancellation enum Status: Sendable { case pending, uploading, completed, failed, cancelled }}
Security-scoped bookmarks: macOS sandboxing requires storing bookmarks to access files selected via the file picker or dropped from Finder.
struct UploadItem: Identifiable, Codable, Sendable { let id: UUID let timestamp: Date let fileName: String let fileSize: Int64 let r2Key: String let publicURL: URL}
enum KeychainService { private static let storageKey = "fiaxe.r2credentials" static func saveAll(_ credentials: [R2Credentials]) throws { let data = try JSONEncoder().encode(credentials) UserDefaults.standard.set(data, forKey: storageKey) } static func loadAll() throws -> [R2Credentials] { guard let data = UserDefaults.standard.data(forKey: storageKey) else { return [] } return try JSONDecoder().decode([R2Credentials].self, from: data) }}
Security note: For a personal single-user tool, credentials are stored in UserDefaults. For multi-user or enterprise apps, use the actual macOS Keychain.
@Observablefinal class UploadHistoryStore { var items: [UploadItem] = [] func add(_ item: UploadItem) { items.insert(item, at: 0) // newest first save() } private func save() { // Encode to JSON and save to UserDefaults }}
enum UpdateService { static func checkForUpdate() async throws -> GitHubRelease? { // Fetch latest release from GitHub API // Compare with current app version // Return release if newer }}