// // ThumbnailProvider.swift // honeyDueQLThumbnail // // Created by Trey Tartt on 12/6/25. // import UIKit import QuickLookThumbnailing class ThumbnailProvider: QLThumbnailProvider { /// Represents the type of .honeydue package private enum PackageType { case contractor case residence } override func provideThumbnail(for request: QLFileThumbnailRequest, _ handler: @escaping (QLThumbnailReply?, Error?) -> Void) { let thumbnailSize = request.maximumSize // Detect package type from file let packageType = detectPackageType(at: request.fileURL) handler(QLThumbnailReply(contextSize: thumbnailSize, currentContextDrawing: { () -> Bool in // Draw background let backgroundColor = UIColor(red: 7/255, green: 160/255, blue: 195/255, alpha: 1) backgroundColor.setFill() UIRectFill(CGRect(origin: .zero, size: thumbnailSize)) // Choose icon based on package type let iconName: String switch packageType { case .contractor: iconName = "person.crop.rectangle.stack" case .residence: iconName = "house.fill" } // Draw icon let config = UIImage.SymbolConfiguration(pointSize: min(thumbnailSize.width, thumbnailSize.height) * 0.5, weight: .regular) if let icon = UIImage(systemName: iconName, withConfiguration: config) { let tintedIcon = icon.withTintColor(.white, renderingMode: .alwaysOriginal) let iconSize = tintedIcon.size let iconOrigin = CGPoint( x: (thumbnailSize.width - iconSize.width) / 2, y: (thumbnailSize.height - iconSize.height) / 2 ) tintedIcon.draw(at: iconOrigin) } return true }), nil) } /// Lightweight struct to detect the package type via Codable instead of JSONSerialization private struct PackageTypeEnvelope: Decodable { let type: String? } /// Detects the package type by reading the "type" field from the JSON private func detectPackageType(at url: URL) -> PackageType { do { let data = try Data(contentsOf: url) let envelope = try JSONDecoder().decode(PackageTypeEnvelope.self, from: data) if envelope.type == "residence" { return .residence } } catch { // Default to contractor on error } return .contractor } }