@@ -14,6 +14,11 @@ final class FilterListStore {
1414 private let parser = FilterListParser ( )
1515 private let logger = Logger ( subsystem: " dev.sweet.diva.nutcracker " , category: " FilterListStore " )
1616
17+ /// How often filter lists are refreshed automatically (7 days).
18+ private static let refreshInterval : TimeInterval = 7 * 24 * 60 * 60
19+ /// How often the auto-update scheduler checks whether a refresh is due.
20+ private static let checkInterval : TimeInterval = 60 * 60
21+
1722 // MARK: - Cache paths
1823
1924 private var cacheDirectory : URL {
@@ -50,13 +55,28 @@ final class FilterListStore {
5055 reparseRules ( )
5156 logger. info ( " Loaded \( self . rules. count) rules from cache " )
5257
53- if let lastUpdated, Date ( ) . timeIntervalSince ( lastUpdated) < 86400 {
58+ if let lastUpdated, Date ( ) . timeIntervalSince ( lastUpdated) < Self . refreshInterval {
5459 return
5560 }
5661
5762 await refreshAllSources ( )
5863 }
5964
65+ /// Schedules recurring automatic refreshes every 7 days. Safe to call once
66+ /// at app launch; the task lives for the lifetime of the store.
67+ func startAutoUpdate( ) {
68+ Task {
69+ while !Task. isCancelled {
70+ try ? await Task . sleep ( nanoseconds: UInt64 ( Self . checkInterval * 1_000_000_000 ) )
71+ guard !Task. isCancelled else { break }
72+ let stale = lastUpdated. map { Date ( ) . timeIntervalSince ( $0) >= Self . refreshInterval } ?? true
73+ if stale {
74+ await refreshAllSources ( )
75+ }
76+ }
77+ }
78+ }
79+
6080 func refreshAllSources( ) async {
6181 isLoading = true
6282 error = nil
0 commit comments