From 9d6f138e40a5322ee731f8096eaa3332c94a6532 Mon Sep 17 00:00:00 2001
From: Ariver <shanghai3168@gmail.com>
Date: Mon, 18 May 2026 17:54:35 +0800
Subject: [PATCH] Speed up repeated app list opens
---
Apptag/DataLayer.swift | 41 ++++++++++++++++++++++++++++++++++++++++-
1 files changed, 40 insertions(+), 1 deletions(-)
diff --git a/Apptag/DataLayer.swift b/Apptag/DataLayer.swift
index 6b0f69a..779beac 100644
--- a/Apptag/DataLayer.swift
+++ b/Apptag/DataLayer.swift
@@ -51,6 +51,10 @@
// MARK: - App Scanner
enum AppIndexer {
+ private static let scanCacheLock = NSLock()
+ private static var cachedScanApps: [AppInfo]? = nil
+ private static var cachedScanAt: Date? = nil
+ private static let scanCacheTTL: TimeInterval = 1800
static let searchPaths: [URL] = [
URL(fileURLWithPath: "/Applications"),
@@ -72,7 +76,42 @@
}
/// Scan all standard locations. Tags are annotated from TagDatabase by the caller.
- static func scan() -> [AppInfo] {
+ static func scan(useCache: Bool = true) -> [AppInfo] {
+ if useCache, let cached = cachedScanIfFresh() {
+ return cached
+ }
+
+ let apps = performScan()
+ updateScanCache(apps)
+ return apps
+ }
+
+ static func invalidateScanCache() {
+ scanCacheLock.lock()
+ cachedScanApps = nil
+ cachedScanAt = nil
+ scanCacheLock.unlock()
+ }
+
+ private static func cachedScanIfFresh() -> [AppInfo]? {
+ scanCacheLock.lock()
+ defer { scanCacheLock.unlock() }
+
+ guard let cachedScanApps,
+ let cachedScanAt,
+ Date().timeIntervalSince(cachedScanAt) < scanCacheTTL
+ else { return nil }
+ return cachedScanApps
+ }
+
+ private static func updateScanCache(_ apps: [AppInfo]) {
+ scanCacheLock.lock()
+ cachedScanApps = apps
+ cachedScanAt = Date()
+ scanCacheLock.unlock()
+ }
+
+ private static func performScan() -> [AppInfo] {
var seenResolvedPaths = Set<String>()
var apps: [AppInfo] = []
--
Gitblit v1.9.3