Files
stickercloner/StickerCloner/StickerCloner MessagesExtension/StickerStore.swift
T

88 lines
2.5 KiB
Swift

import Foundation
import Messages
final class StickerStore {
static let shared = StickerStore()
private let packsKey = "savedPacks"
private let defaults = UserDefaults.standard
private let fileManager = FileManager.default
private init() {}
// MARK: - Pack persistence
var savedPacks: [SavedPack] {
get {
guard let data = defaults.data(forKey: packsKey) else { return [] }
return (try? JSONDecoder().decode([SavedPack].self, from: data)) ?? []
}
set {
let data = try? JSONEncoder().encode(newValue)
defaults.set(data, forKey: packsKey)
}
}
// MARK: - File management
private var stickersDirectory: URL {
let caches = fileManager.urls(for: .cachesDirectory, in: .userDomainMask).first!
return caches.appendingPathComponent("stickers", isDirectory: true)
}
private func packDirectory(name: String) -> URL {
stickersDirectory.appendingPathComponent(name, isDirectory: true)
}
// MARK: - Add / remove packs
func addPack(response: StickerSetResponse) async throws {
let pack = SavedPack(name: response.name, title: response.title, stickerCount: response.stickerCount)
// Download all sticker PNGs
let packDir = packDirectory(name: response.name)
try fileManager.createDirectory(at: packDir, withIntermediateDirectories: true)
for sticker in response.stickers {
let localURL = packDir.appendingPathComponent("\(sticker.id).png")
if fileManager.fileExists(atPath: localURL.path) { continue }
try await StickerClonerAPI.downloadSticker(from: sticker.pngUrl, to: localURL)
}
// Save metadata after successful download
var packs = savedPacks
packs.removeAll { $0.name == pack.name }
packs.append(pack)
savedPacks = packs
}
func removePack(name: String) {
var packs = savedPacks
packs.removeAll { $0.name == name }
savedPacks = packs
let packDir = packDirectory(name: name)
try? fileManager.removeItem(at: packDir)
}
// MARK: - Load stickers for display
func loadStickers() -> [MSSticker] {
var stickers: [MSSticker] = []
for pack in savedPacks {
let packDir = packDirectory(name: pack.name)
guard let files = try? fileManager.contentsOfDirectory(at: packDir, includingPropertiesForKeys: nil) else { continue }
for file in files.sorted(by: { $0.lastPathComponent < $1.lastPathComponent }) {
guard file.pathExtension == "png" else { continue }
if let sticker = try? MSSticker(contentsOfFileURL: file, localizedDescription: pack.title) {
stickers.append(sticker)
}
}
}
return stickers
}
}