Skip to content

Commit c5f6404

Browse files
committed
Trying to move the initial state setup before onAppear to fix the watchOS switching url or any other state issue
This maybe a behavior changes, need testing
1 parent 8b26cb7 commit c5f6404

File tree

4 files changed

+68
-114
lines changed

4 files changed

+68
-114
lines changed

SDWebImageSwiftUI/Classes/ImageManager.swift

Lines changed: 39 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,47 @@ import SDWebImage
1515
@available(iOS 14.0, OSX 11.0, tvOS 14.0, watchOS 7.0, *)
1616
public final class ImageManager : ObservableObject {
1717
/// loaded image, note when progressive loading, this will published multiple times with different partial image
18-
@Published public var image: PlatformImage?
18+
public var image: PlatformImage? {
19+
didSet {
20+
DispatchQueue.main.async {
21+
self.objectWillChange.send()
22+
}
23+
}
24+
}
1925
/// loaded image data, may be nil if hit from memory cache. This will only published once even on incremental image loading
20-
@Published public var imageData: Data?
26+
public var imageData: Data? {
27+
didSet {
28+
DispatchQueue.main.async {
29+
self.objectWillChange.send()
30+
}
31+
}
32+
}
2133
/// loaded image cache type, .none means from network
22-
@Published public var cacheType: SDImageCacheType = .none
34+
public var cacheType: SDImageCacheType = .none {
35+
didSet {
36+
DispatchQueue.main.async {
37+
self.objectWillChange.send()
38+
}
39+
}
40+
}
2341
/// loading error, you can grab the error code and reason listed in `SDWebImageErrorDomain`, to provide a user interface about the error reason
24-
@Published public var error: Error?
42+
public var error: Error? {
43+
didSet {
44+
DispatchQueue.main.async {
45+
self.objectWillChange.send()
46+
}
47+
}
48+
}
2549
/// true means during incremental loading
26-
@Published public var isIncremental: Bool = false
50+
public var isIncremental: Bool = false {
51+
didSet {
52+
DispatchQueue.main.async {
53+
self.objectWillChange.send()
54+
}
55+
}
56+
}
2757
/// A observed object to pass through the image manager loading status to indicator
28-
@Published public var indicatorStatus = IndicatorStatus()
58+
public var indicatorStatus = IndicatorStatus()
2959

3060
weak var currentOperation: SDWebImageOperation? = nil
3161

@@ -51,8 +81,8 @@ public final class ImageManager : ObservableObject {
5181
return
5282
}
5383
currentURL = url
54-
indicatorStatus.isLoading = true
55-
indicatorStatus.progress = 0
84+
self.indicatorStatus.isLoading = true
85+
self.indicatorStatus.progress = 0
5686
currentOperation = manager.loadImage(with: url, options: options, context: context, progress: { [weak self] (receivedSize, expectedSize, _) in
5787
guard let self = self else {
5888
return
@@ -63,9 +93,7 @@ public final class ImageManager : ObservableObject {
6393
} else {
6494
progress = 0
6595
}
66-
DispatchQueue.main.async {
67-
self.indicatorStatus.progress = progress
68-
}
96+
self.indicatorStatus.progress = progress
6997
self.progressBlock?(receivedSize, expectedSize)
7098
}) { [weak self] (image, data, error, cacheType, finished, _) in
7199
guard let self = self else {

SDWebImageSwiftUI/Classes/Indicator/Indicator.swift

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,21 @@ public struct Indicator<T> where T : View {
2828
@available(iOS 14.0, OSX 11.0, tvOS 14.0, watchOS 7.0, *)
2929
public class IndicatorStatus : ObservableObject {
3030
/// whether indicator is loading or not
31-
@Published var isLoading: Bool = false
31+
var isLoading: Bool = false {
32+
didSet {
33+
DispatchQueue.main.async {
34+
self.objectWillChange.send()
35+
}
36+
}
37+
}
3238
/// indicator progress, should only be used for indicator binding, value between [0.0, 1.0]
33-
@Published var progress: Double = 0
39+
var progress: Double = 0 {
40+
didSet {
41+
DispatchQueue.main.async {
42+
self.objectWillChange.send()
43+
}
44+
}
45+
}
3446
}
3547

3648
/// A implementation detail View Modifier with indicator

SDWebImageSwiftUI/Classes/SwiftUICompatibility.swift

Lines changed: 0 additions & 92 deletions
This file was deleted.

SDWebImageSwiftUI/Classes/WebImage.swift

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -163,26 +163,22 @@ public struct WebImage<Content> : View where Content: View {
163163
}
164164
} else {
165165
content((imageManager.error != nil) ? .failure(imageManager.error!) : .empty)
166-
setupPlaceholder()
166+
setupInitialState()
167167
// Load Logic
168-
.onPlatformAppear(appear: {
169-
self.setupManager()
170-
if (self.imageManager.error == nil) {
171-
// Load remote image when first appear
172-
self.imageManager.load(url: imageModel.url, options: imageModel.options, context: imageModel.context)
173-
}
168+
.onAppear {
174169
guard self.imageConfiguration.retryOnAppear else { return }
175170
// When using prorgessive loading, the new partial image will cause onAppear. Filter this case
176171
if self.imageManager.error != nil && !self.imageManager.isIncremental {
177172
self.imageManager.load(url: imageModel.url, options: imageModel.options, context: imageModel.context)
178173
}
179-
}, disappear: {
174+
}
175+
.onDisappear {
180176
guard self.imageConfiguration.cancelOnDisappear else { return }
181177
// When using prorgessive loading, the previous partial image will cause onDisappear. Filter this case
182178
if self.imageManager.error != nil && !self.imageManager.isIncremental {
183179
self.imageManager.cancel()
184180
}
185-
})
181+
}
186182
}
187183
}
188184
}
@@ -328,6 +324,16 @@ public struct WebImage<Content> : View where Content: View {
328324
}
329325
}
330326

327+
/// Initial state management (update when imageModel.url changed)
328+
func setupInitialState() -> some View {
329+
self.setupManager()
330+
if (self.imageManager.error == nil) {
331+
// Load remote image when first appear
332+
self.imageManager.load(url: imageModel.url, options: imageModel.options, context: imageModel.context)
333+
}
334+
return setupPlaceholder()
335+
}
336+
331337
/// Placeholder View Support
332338
func setupPlaceholder() -> some View {
333339
let result = content((imageManager.error != nil) ? .failure(imageManager.error!) : .empty)

0 commit comments

Comments
 (0)