Skip to content

Commit 1994159

Browse files
committed
Merge branch 'kean-master'
Updated fork with latest upstream changes.
2 parents 944269d + cefd438 commit 1994159

File tree

2 files changed

+27
-128
lines changed

2 files changed

+27
-128
lines changed

README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,6 @@ private func withoutAnimation(_ closure: () -> Void) {
113113
var transaction = Transaction(animation: nil)
114114
transaction.disablesAnimations = true
115115
withTransaction(transaction, closure)
116-
}
117116
```
118117

119118
### Firebase

Source/FetchImage.swift

Lines changed: 27 additions & 127 deletions
Original file line numberDiff line numberDiff line change
@@ -9,44 +9,14 @@ import FirebaseStorage
99
/// Fetch a remote image and progressively load using cached resources first, if
1010
/// available, then displaying a placeholder until fully loaded.
1111
///
12-
/// - warning: This is an API preview. It is not battle-tested yet and might
13-
/// signficantly change in the future.
14-
///
1512
public final class FetchImage: ObservableObject, Identifiable {
1613

1714
// MARK: - Paramaters
1815

1916
/// The original request.
20-
public private(set) var request: ImageRequest? {
21-
didSet {
22-
assert(Thread.isMainThread, "Only modify the request from the main thread.")
23-
if currentlyLoadingImageQuality == .regular {
24-
cancel()
25-
}
26-
guard let newRequest = request else {
27-
if loadedImageQuality == .regular {
28-
image = nil
29-
}
30-
return
31-
}
32-
priority = newRequest.priority
33-
}
34-
}
35-
36-
/// The request to be performed if the original request fails with
37-
/// `networkUnavailableReason` `.constrained` (low data mode).
38-
public private(set) var lowDataRequest: ImageRequest? {
39-
didSet {
40-
assert(Thread.isMainThread, "Only modify the request from the main thread.")
41-
if currentlyLoadingImageQuality == .low {
42-
cancel()
43-
}
44-
if lowDataRequest == nil && loadedImageQuality == .low {
45-
image = nil
46-
}
47-
}
48-
}
49-
17+
///
18+
public private(set) var request: ImageRequest?
19+
5020
/// Returns the fetched image.
5121
///
5222
/// - note: In case pipeline has `isProgressiveDecodingEnabled` option enabled
@@ -79,42 +49,17 @@ public final class FetchImage: ObservableObject, Identifiable {
7949

8050
public var pipeline: ImagePipeline = .shared
8151
private var task: ImageTask?
82-
private var loadedImageQuality: ImageQuality?
83-
private var currentlyLoadingImageQuality: ImageQuality? = nil
84-
85-
private enum ImageQuality {
86-
case regular
87-
case low
88-
}
89-
9052

9153
// MARK: - Lifecycle
9254

9355
deinit {
9456
cancel()
9557
}
96-
97-
public init() {
98-
99-
}
100-
101-
/// Loads an image with a regular URL and an optional low-data URL.
102-
///
103-
/// If supplying an optional low-data URL, disables constrained network access on
104-
/// the full size request. If the download fails on the initial full size URL, falls
105-
/// back to the low-data URL.
106-
///
107-
/// - parameter url: The remote image URL
108-
/// - parameter lowDataUrl: The low data remote image URL
109-
///
110-
public func load(_ url: URL, lowDataUrl: URL? = nil) {
111-
var request = URLRequest(url: url)
112-
if let constrainedURL = lowDataUrl {
113-
request.allowsConstrainedNetworkAccess = false
114-
load(ImageRequest(urlRequest: request), lowDataRequest: ImageRequest(url: constrainedURL))
115-
} else {
116-
load(ImageRequest(url: url))
117-
}
58+
59+
public init() {}
60+
61+
public func load(_ url: URL) {
62+
self.load(ImageRequest(url: url))
11863
}
11964

12065
/// Initializes the fetch request with a Firebase Storage Reference to an image in
@@ -123,32 +68,28 @@ public final class FetchImage: ObservableObject, Identifiable {
12368
///
12469
/// - parameter regularStorageRef: A `StorageReference` which points to a
12570
/// Firebase Storage file in any of Nuke's supported image formats.
126-
/// - parameter lowDataStorageRef: A `StorageReference` which points to a smaller
127-
/// Firebase Storage file in any of Nuke's supported image formats, which is also
128-
/// appropriate for low-data scenarios.
12971
/// - parameter uniqueURL: A caller to request any potentially cached image URLs.
13072
/// Implementing your own URL caching prevents potentially unnecessary roundtrips to
13173
/// your Firebase Storage bucket.
13274
/// - parameter finished: Called when URL loading has completed and fetching can
13375
/// begin. If the caller is `nil`, a fetch operation is queued immediately.
13476
///
135-
public func load(regularStorageRef: StorageReference, lowDataStorageRef: StorageReference? = nil,
136-
uniqueURL: (() -> URL?)? = nil, finished: ((URL?) -> Void)? = nil) {
137-
func finishOrLoad(_ request: ImageRequest, lowDataRequest: ImageRequest? = nil, discoveredURL: URL? = nil) {
77+
public func load(regularStorageRef: StorageReference, uniqueURL: (() -> URL?)? = nil, finished: ((URL?) -> Void)? = nil) {
78+
func finishOrLoad(_ request: ImageRequest, discoveredURL: URL? = nil) {
13879
if let completionBlock = finished {
13980
completionBlock(discoveredURL)
14081
}
14182
load(request)
14283
}
14384

144-
func getRegularURL(lowDataRequest: ImageRequest? = nil) {
85+
func getRegularURL() {
14586
regularStorageRef.downloadURL { (discoveredURL, error) in
14687
if let given = discoveredURL {
14788
let newRequest = ImageRequest(url: given)
14889
self.request = newRequest
14990
self.priority = newRequest.priority
15091

151-
finishOrLoad(newRequest, lowDataRequest: lowDataRequest, discoveredURL: given)
92+
finishOrLoad(newRequest, discoveredURL: given)
15293
} else {
15394
finished?(discoveredURL)
15495
}
@@ -168,22 +109,9 @@ public final class FetchImage: ObservableObject, Identifiable {
168109
}
169110
}
170111

171-
if let lowDataRef = lowDataStorageRef {
172-
lowDataRef.downloadURL { (discoveredURL, error) in
173-
if let given = discoveredURL {
174-
let constrainedRequest = ImageRequest(url: given)
175-
self.lowDataRequest = constrainedRequest
176-
getRegularURL(lowDataRequest: constrainedRequest)
177-
} else {
178-
getRegularURL()
179-
}
180-
}
181-
} else {
182-
getRegularURL()
183-
}
112+
getRegularURL()
184113
}
185114

186-
187115
// MARK: - Fetching
188116

189117
/// Starts loading the image if not already loaded and the download is not already
@@ -195,7 +123,7 @@ public final class FetchImage: ObservableObject, Identifiable {
195123
/// image. If the first attempt fails, the next time you call `fetch`, it is going
196124
/// to attempt to fetch the regular quality image again.
197125
///
198-
public func load(_ request: ImageRequest, lowDataRequest: ImageRequest? = nil) {
126+
public func load(_ request: ImageRequest) {
199127
_reset()
200128

201129
// Cancel previous task after starting a new one to make sure that if
@@ -205,24 +133,18 @@ public final class FetchImage: ObservableObject, Identifiable {
205133
defer { previousTask?.cancel() }
206134

207135
self.request = request
208-
self.lowDataRequest = lowDataRequest
209136

210137
// Try to display the regular image if it is available in memory cache
211138
if let container = pipeline.cachedImage(for: request) {
212-
(image, loadedImageQuality) = (container.image, .regular)
139+
image = container.image
213140
return // Nothing to do
214141
}
215142

216-
// Try to display the low data image and retry loading the regular image
217-
if let container = lowDataRequest.flatMap(pipeline.cachedImage(for:)) {
218-
(image, loadedImageQuality) = (container.image, .low)
219-
}
220-
221143
isLoading = true
222-
load(request: request, quality: .regular)
144+
_load(request: request)
223145
}
224-
225-
private func load(request: ImageRequest, quality: ImageQuality) {
146+
147+
private func _load(request: ImageRequest) {
226148
progress = Progress(completed: 0, total: 0)
227149
currentlyLoadingImageQuality = quality
228150

@@ -238,36 +160,25 @@ public final class FetchImage: ObservableObject, Identifiable {
238160
}
239161
},
240162
completion: { [weak self] in
241-
self?.didFinishRequest(result: $0, quality: quality)
163+
self?.didFinishRequest(result: $0)
242164
}
243165
)
244166

245167
if priority != request.priority {
246168
task?.priority = priority
247169
}
248170
}
249-
250-
private func didFinishRequest(result: Result<ImageResponse, ImagePipeline.Error>, quality: ImageQuality) {
171+
172+
private func didFinishRequest(result: Result<ImageResponse, ImagePipeline.Error>) {
251173
task = nil
252-
currentlyLoadingImageQuality = nil
174+
isLoading = false
253175

254176
switch result {
255177
case let .success(response):
256-
isLoading = false
257-
(image, loadedImageQuality) = (response.image, quality)
178+
self.image = response.image
258179
case let .failure(error):
259-
// If the regular request fails because of the low data mode,
260-
// use an alternative source.
261-
if quality == .regular, error.isConstrainedNetwork, let request = self.lowDataRequest {
262-
if loadedImageQuality == .low {
263-
isLoading = false // Low-quality image already loaded
264-
} else {
265-
load(request: request, quality: .low)
266-
}
267-
} else {
268-
self.error = error
269-
isLoading = false
270-
}
180+
self.error = error
181+
isLoading = false
271182
}
272183
}
273184

@@ -289,25 +200,14 @@ public final class FetchImage: ObservableObject, Identifiable {
289200
cancel()
290201
_reset()
291202
}
292-
203+
293204
private func _reset() {
294205
isLoading = false
295206
image = nil
296207
error = nil
297208
progress = Progress(completed: 0, total: 0)
298209
loadedImageQuality = nil
299-
}
300-
301-
}
302-
303-
private extension ImagePipeline.Error {
304-
305-
var isConstrainedNetwork: Bool {
306-
if case let .dataLoadingFailed(error) = self,
307-
(error as? URLError)?.networkUnavailableReason == .constrained {
308-
return true
309-
}
310-
return false
210+
request = nil
311211
}
312212

313213
}

0 commit comments

Comments
 (0)