-
-
Notifications
You must be signed in to change notification settings - Fork 68
/
ImageCache.swift
83 lines (76 loc) · 2.99 KB
/
ImageCache.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#if canImport(AppKit)
import AppKit
import Foundation
#else
import UIKit
#endif
final actor ImageCache {
static let shared = ImageCache()
nonisolated let cacheDirectory: String = {
let fileManager = FileManager.default
let appSupportURL = fileManager.urls(for: .cachesDirectory, in: .userDomainMask).first!
return appSupportURL.appendingPathComponent("build.bru.Trailer").path
}()
private init() {
let fileManager = FileManager.default
if fileManager.fileExists(atPath: cacheDirectory) {
Task {
await expireAncientFiles()
}
} else {
try! fileManager.createDirectory(atPath: cacheDirectory, withIntermediateDirectories: true, attributes: nil)
}
}
func store(_ image: IMAGE_CLASS, from url: String) -> URL? {
let filename = "\(cacheDirectory)/\(url.fileHash).bin"
let url = URL(fileURLWithPath: filename)
do {
#if canImport(AppKit)
if let cgImage = image.cgImage(forProposedRect: nil, context: nil, hints: nil),
let jpg = NSBitmapImageRep(cgImage: cgImage).representation(using: .jpeg, properties: [:]) {
try jpg.write(to: url)
return url
}
#else
if let jpg = image.jpegData(compressionQuality: 0.7) {
try jpg.write(to: url)
return url
}
#endif
} catch {}
return nil
}
private func expireAncientFiles() {
let now = Date()
let fileManager = FileManager.default
for f in try! fileManager.contentsOfDirectory(atPath: cacheDirectory) {
do {
let path = cacheDirectory.appending(pathComponent: f)
if path.hasSuffix(".etag") {
try fileManager.removeItem(atPath: path)
Task {
await Logging.shared.log("Removed old cached data: \(path)")
}
} else if path.hasSuffix(".bin") {
let attributes = try fileManager.attributesOfItem(atPath: path)
if let date = attributes[.creationDate] as? Date {
if now.timeIntervalSince(date) > (3600 * 24 * 30) {
try fileManager.removeItem(atPath: path)
Task {
await Logging.shared.log("Removed old cached data: \(path)")
}
}
} else {
Task {
await Logging.shared.log("Removed cached data with no modification date: \(path)")
}
}
}
} catch {
Task {
await Logging.shared.log("File error when removing old cached data: \(error.localizedDescription)")
}
}
}
}
}