@@ -21,9 +21,11 @@ public class URLRequestHeater<Object: WarmableURL> {
21
21
22
22
private let creationClosure : ( ) -> Object
23
23
24
- internal var pool : [ String : Object ] = [ : ]
25
24
internal let anonymousHeater : Heater < Object >
26
-
25
+ internal var pool : [ URLRequest : Object ] = [ : ]
26
+ internal var objectsLivespan : [ URLRequest : TimeInterval ] = [ : ]
27
+ internal var livespanTimer : Timer ? = nil
28
+
27
29
/**
28
30
Initialize a **URLRequestHeater** with **creationClosure** as the block of code to init its objects
29
31
@@ -39,27 +41,51 @@ public class URLRequestHeater<Object: WarmableURL> {
39
41
self . creationClosure = creationClosure
40
42
self . anonymousHeater = Heater < Object > ( creationClosure: creationClosure)
41
43
}
44
+
45
+ private func checkLivespanTimer( ) {
46
+ if livespanTimer != nil { return }
47
+ if let livespanTimer = livespanTimer, livespanTimer. isValid {
48
+ return
49
+ }
50
+ livespanTimer = Timer . scheduledTimer ( withTimeInterval: 1 , repeats: true , block: { [ weak self] _ in
51
+ guard let self = self else { return }
52
+ let now = Date ( ) . timeIntervalSinceReferenceDate
53
+ self . objectsLivespan. forEach { ( urlRequest, livespan) in
54
+ if now > livespan, let object = self . pool [ urlRequest] {
55
+ DispatchQueue . main. async {
56
+ object. warmUp ( with: urlRequest)
57
+ }
58
+ }
59
+ }
60
+ } )
61
+ }
42
62
}
43
63
44
64
/// Extension for (URL) named objects pool
45
65
public extension URLRequestHeater {
46
66
47
67
/// starts warming up a new **Object** identified by an **URL**
48
68
/// - Parameter url: an URL that will be sent as param in the creation closure.
69
+ /// - Parameter livespan: number of seconds of life of this warmed up object. It reloads the cache when the livespan ends.
49
70
/// Object is identified by this url
50
- func warmUp( with url: URL ) {
71
+ func warmUp( with url: URL , livespan : TimeInterval ? = nil ) {
51
72
let urlRequest = URLRequest ( url: url)
52
- warmUp ( with: urlRequest)
73
+ warmUp ( with: urlRequest, livespan : livespan )
53
74
}
54
75
55
76
/// starts warming up a new **Object** identified by an **urlString**
56
77
/// - Parameter request: an URL Request that will be sent as param in the creation closure.
78
+ /// - Parameter livespan: number of seconds of life of this warmed up object. It reloads the cache when the livespan ends.
57
79
/// Object is identified by its absolute URL String.
58
- func warmUp( with request: URLRequest ) {
59
- guard let url = request. url else { return }
80
+ func warmUp( with request: URLRequest , livespan: TimeInterval ? = nil ) {
60
81
let object = creationClosure ( )
61
82
object. warmUp ( with: request)
62
- pool [ url. absoluteString] = object
83
+ pool [ request] = object
84
+ if let livespan = livespan {
85
+ let endsDate = Date ( ) . timeIntervalSinceReferenceDate + livespan
86
+ objectsLivespan [ request] = endsDate
87
+ checkLivespanTimer ( )
88
+ }
63
89
}
64
90
}
65
91
@@ -73,25 +99,27 @@ public extension URLRequestHeater {
73
99
74
100
/// Dequeues a named object if available
75
101
/// - Parameter url: an URL that identifies the warmed-up object
76
- /// - Returns: an **Object** if exists in the **URLRequestHeater** pool of objects, **nil** otherwise
77
- func dequeue( with url: URL ) -> Object ? {
78
- let urlString = url. absoluteString
79
- guard let warmedUpObject = pool [ urlString] else {
80
- return nil
81
- }
82
- pool. removeValue ( forKey: urlString)
83
- return warmedUpObject
102
+ /// - Returns: a warmed up **Object** if exists in the **URLRequestHeater** pool of objects, or a new one.
103
+ func dequeue( with url: URL ) -> Object {
104
+ let urlRequest = URLRequest ( url: url)
105
+ return dequeue ( with: urlRequest)
84
106
}
85
107
86
108
/// Dequeues a named object if available
87
109
/// - Parameter request: an URL Request, which absolute URL identifies the warmed-up object
88
- /// - Returns: an **Object** if exists in the **URLRequestHeater** pool of objects, **nil** otherwise
89
- func dequeue( with request: URLRequest ) -> Object ? {
90
- guard let url = request. url,
91
- let warmedUpObject = pool [ url. absoluteString] else {
92
- return nil
110
+ /// - Returns: a warmed up **Object** if exists in the **URLRequestHeater** pool of objects, or a new one.
111
+ func dequeue( with request: URLRequest ) -> Object {
112
+ guard let warmedUpObject = pool [ request] else {
113
+ let object = dequeue ( )
114
+ object. warmUp ( with: request)
115
+ return object
93
116
}
94
- pool. removeValue ( forKey: url. absoluteString)
117
+ pool. removeValue ( forKey: request)
118
+ objectsLivespan. removeValue ( forKey: request)
119
+ if objectsLivespan. isEmpty {
120
+ livespanTimer? . invalidate ( )
121
+ livespanTimer = nil
122
+ }
95
123
return warmedUpObject
96
124
}
97
125
}
0 commit comments