Skip to content

Commit 66202c0

Browse files
committed
Add reload image if the URL on change.
1 parent 4eed39d commit 66202c0

5 files changed

Lines changed: 29 additions & 37 deletions

File tree

README.md

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,11 @@ CachedAsyncImage(
4747
**Note:** The default value is `0`, e.g. is no count limit and is no total cost limit.
4848

4949
```swift
50-
.onAppear {
51-
// Set image cache limit.
52-
TemporaryImageCache.shared.setCacheLimit(
53-
countLimit: 1000, // 1000 items
54-
totalCostLimit: 1024 * 1024 * 200 // 200 MB
55-
)
56-
}
50+
// Set image cache limit.
51+
TemporaryImageCache.shared.setCacheLimit(
52+
countLimit: 1000, // 1000 items
53+
totalCostLimit: 1024 * 1024 * 200 // 200 MB
54+
)
5755
```
5856

5957
## Requirements

Sources/CachedAsyncImage/Services/ImageLoader.swift

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ final class ImageLoader: ObservableObject {
1616

1717
// MARK: - Private Properties
1818

19-
private let url: URL?
2019
private let networkManager: NetworkManagerProtocol
2120
private let imageCache = TemporaryImageCache.shared
2221

@@ -29,11 +28,7 @@ final class ImageLoader: ObservableObject {
2928

3029
// MARK: - Initializers
3130

32-
init(
33-
url: URL?,
34-
networkManager: NetworkManagerProtocol
35-
) {
36-
self.url = url
31+
init(networkManager: NetworkManagerProtocol) {
3732
self.networkManager = networkManager
3833
}
3934

@@ -45,9 +40,11 @@ final class ImageLoader: ObservableObject {
4540

4641
// MARK: - Public Methods
4742

48-
func fetchImage() {
43+
func fetchImage(from url: String) {
4944
guard !isLoading else { return }
5045

46+
let url = URL(string: url)
47+
5148
if let url = url, let cachedImage = imageCache[url] {
5249
image = cachedImage
5350
return
@@ -61,7 +58,7 @@ final class ImageLoader: ObservableObject {
6158
self?.start()
6259
},
6360
receiveOutput: { [weak self] in
64-
self?.cache($0)
61+
self?.cache(url: url, image: $0)
6562
},
6663
receiveCompletion: { [weak self] _ in
6764
self?.finish()
@@ -87,7 +84,7 @@ final class ImageLoader: ObservableObject {
8784
isLoading = false
8885
}
8986

90-
private func cache(_ image: UIImage?) {
87+
private func cache(url: URL?, image: UIImage?) {
9188
guard let url = url else { return }
9289
image.map { imageCache[url] = $0 }
9390
}

Sources/CachedAsyncImage/Services/NetworkManager.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,7 @@ final class NetworkManager: NetworkManagerProtocol {
5353

5454
#if DEBUG
5555
let message = """
56-
****
57-
CachedAsyncImage response.
56+
**** CachedAsyncImage response.
5857
From: \(urlResponse.url?.absoluteString ?? "")
5958
Status code: \(urlResponse.statusCode)
6059
"""

Sources/CachedAsyncImage/Views/CachedAsyncImage.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,17 @@ public struct CachedAsyncImage: View {
1616

1717
// MARK: - Private Properties
1818

19+
private let url: String
1920
private let placeholder: (() -> any View)?
2021
private let image: (UIImage) -> any View
2122

2223
// MARK: - Body
2324

2425
public var body: some View {
2526
content
27+
.onChange(of: url, perform: { imageLoader.fetchImage(from: $0) })
2628
.onAppear {
27-
imageLoader.fetchImage()
29+
imageLoader.fetchImage(from: url)
2830
}
2931
}
3032

@@ -40,12 +42,10 @@ public struct CachedAsyncImage: View {
4042
image: @escaping (UIImage) -> any View
4143
) {
4244
_imageLoader = StateObject(
43-
wrappedValue: ImageLoader(
44-
url: URL(string: url),
45-
networkManager: NetworkManager.shared
46-
)
45+
wrappedValue: ImageLoader(networkManager: NetworkManager.shared)
4746
)
4847

48+
self.url = url
4949
self.placeholder = placeholder
5050
self.image = image
5151
}

Tests/CachedAsyncImageTests/ImageLoaderTests.swift

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -27,21 +27,20 @@ final class ImageLoaderTests: XCTestCase {
2727

2828
func testFetchImage_WithCachedImage() {
2929
// Given
30-
let imageUrl = URL(string: "https://example.com/image.jpg")
30+
let url = "https://example.com/image.jpg"
3131
let networkManager = sut.networkManager
3232
let imageCache = sut.imageCache
3333
let cachedImage = RM.image("backToTheFuture")
3434

35-
let imageLoader = ImageLoader(
36-
url: imageUrl,
37-
networkManager: networkManager
38-
)
35+
let imageLoader = ImageLoader(networkManager: networkManager)
3936

4037
// When
41-
guard let imageUrl = imageUrl else { fatalError("Bad URL or nil.") }
38+
guard let imageUrl = URL(string: url) else {
39+
fatalError("Bad URL or nil.")
40+
}
4241

4342
imageCache[imageUrl] = cachedImage
44-
imageLoader.fetchImage()
43+
imageLoader.fetchImage(from: url)
4544

4645
// Then
4746
XCTAssertNotNil(imageLoader.image, "Image should be not nil.")
@@ -56,21 +55,20 @@ final class ImageLoaderTests: XCTestCase {
5655

5756
func testFetchImage_WithoutCachedImage() {
5857
// Given
59-
let imageUrl = URL(string: "https://example.com/image.jpg")
58+
let url = "https://example.com/image.jpg"
6059
let networkManager = sut.networkManager
6160
let imageCache = sut.imageCache
6261
imageCache.removeCache()
6362

64-
let imageLoader = ImageLoader(
65-
url: imageUrl,
66-
networkManager: networkManager
67-
)
63+
let imageLoader = ImageLoader(networkManager: networkManager)
6864

6965
// When
70-
imageLoader.fetchImage()
66+
imageLoader.fetchImage(from: url)
7167

7268
// Then
73-
guard let imageUrl = imageUrl else { fatalError("Bad URL or nil.") }
69+
guard let imageUrl = URL(string: url) else {
70+
fatalError("Bad URL or nil.")
71+
}
7472

7573
XCTAssertNil(imageCache[imageUrl], "Image cache should be nil.")
7674

0 commit comments

Comments
 (0)