1import AppKit23@MainActor4protocol WallpaperManaging {5 func download(from url: URL) async throws -> URL6 func setDesktopImage(from fileURL: URL, screen: NSScreen?) throws7 func saveToFolder(from sourceURL: URL, to folderURL: URL) throws8}910class WallpaperManager: WallpaperManaging {11 static let shared = WallpaperManager()1213 private let session: URLSession14 private let desktopSetter: @MainActor (URL, NSScreen) throws -> Void1516 init(17 session: URLSession = .shared,18 desktopSetter: @escaping @MainActor (URL, NSScreen) throws -> Void =19 WallpaperManager.applyDesktopImage20 ) {21 self.session = session22 self.desktopSetter = desktopSetter23 }2425 private static func applyDesktopImage(_ url: URL, _ screen: NSScreen) throws {26 try NSWorkspace.shared.setDesktopImageURL(url, for: screen, options: [:])27 }2829 30 func download(from url: URL) async throws -> URL {31 let (data, response) = try await session.data(from: url)32 guard let response = response as? HTTPURLResponse,33 (200...299).contains(response.statusCode)34 else {35 throw WallhavenError.apiError("Wallpaper download failed")36 }3738 let filename = url.lastPathComponent39 let tempDir = FileManager.default.temporaryDirectory40 let fileURL = tempDir.appendingPathComponent(filename)4142 try data.write(to: fileURL)43 return fileURL44 }4546 47 @MainActor48 func setDesktopImage(from fileURL: URL, screen: NSScreen? = nil) throws {49 if let screen = screen {50 try desktopSetter(fileURL, screen)51 } else {52 53 54 55 let targetScreen = NSScreen.main ?? NSScreen.screens.first!56 try desktopSetter(fileURL, targetScreen)57 }58 }5960 61 func saveToFolder(from sourceURL: URL, to folderURL: URL) throws {62 63 try FileManager.default.createDirectory(at: folderURL, withIntermediateDirectories: true)6465 let destinationURL = folderURL.appendingPathComponent(sourceURL.lastPathComponent)6667 68 69 if FileManager.default.fileExists(atPath: destinationURL.path) {70 try FileManager.default.removeItem(at: destinationURL)71 }7273 try FileManager.default.copyItem(at: sourceURL, to: destinationURL)74 }7576 77 @MainActor78 func setWallpaper(from url: URL, screen: NSScreen? = nil) async throws {79 let localURL = try await download(from: url)80 try setDesktopImage(from: localURL, screen: screen)81 }82}