60 lines
1.9 KiB
Swift
60 lines
1.9 KiB
Swift
import Foundation
|
|
|
|
enum StickerClonerAPIError: LocalizedError {
|
|
case invalidResponse(Int)
|
|
case decodingFailed(Error)
|
|
|
|
var errorDescription: String? {
|
|
switch self {
|
|
case .invalidResponse(let code):
|
|
return "Server returned status \(code)"
|
|
case .decodingFailed(let error):
|
|
return "Failed to decode response: \(error.localizedDescription)"
|
|
}
|
|
}
|
|
}
|
|
|
|
enum StickerClonerAPI {
|
|
private static let baseURL = URL(string: "https://serve.uber.space/sticker-cloner")!
|
|
|
|
private static let decoder: JSONDecoder = {
|
|
let d = JSONDecoder()
|
|
d.keyDecodingStrategy = .convertFromSnakeCase
|
|
return d
|
|
}()
|
|
|
|
static func fetchStickerSet(name: String) async throws -> StickerSetResponse {
|
|
let url = baseURL.appendingPathComponent("api/stickersets/\(name)")
|
|
let (data, response) = try await URLSession.shared.data(from: url)
|
|
|
|
guard let http = response as? HTTPURLResponse, 200..<300 ~= http.statusCode else {
|
|
let code = (response as? HTTPURLResponse)?.statusCode ?? -1
|
|
throw StickerClonerAPIError.invalidResponse(code)
|
|
}
|
|
|
|
do {
|
|
return try decoder.decode(StickerSetResponse.self, from: data)
|
|
} catch {
|
|
throw StickerClonerAPIError.decodingFailed(error)
|
|
}
|
|
}
|
|
|
|
static func downloadSticker(from relativePath: String, to localURL: URL) async throws {
|
|
let url = baseURL.appendingPathComponent(relativePath)
|
|
let (tempURL, response) = try await URLSession.shared.download(from: url)
|
|
|
|
guard let http = response as? HTTPURLResponse, 200..<300 ~= http.statusCode else {
|
|
let code = (response as? HTTPURLResponse)?.statusCode ?? -1
|
|
throw StickerClonerAPIError.invalidResponse(code)
|
|
}
|
|
|
|
let directory = localURL.deletingLastPathComponent()
|
|
try FileManager.default.createDirectory(at: directory, withIntermediateDirectories: true)
|
|
|
|
if FileManager.default.fileExists(atPath: localURL.path) {
|
|
try FileManager.default.removeItem(at: localURL)
|
|
}
|
|
try FileManager.default.moveItem(at: tempURL, to: localURL)
|
|
}
|
|
}
|