Skip to content

Commit

Permalink
Trying to move the initial state setup before onAppear to fix the w…
Browse files Browse the repository at this point in the history
…atchOS switching url or any other state issue

This maybe a behavior changes, need testing
  • Loading branch information
dreampiggy committed Apr 29, 2024
1 parent 8b26cb7 commit c5f6404
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 114 deletions.
50 changes: 39 additions & 11 deletions SDWebImageSwiftUI/Classes/ImageManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,47 @@ import SDWebImage
@available(iOS 14.0, OSX 11.0, tvOS 14.0, watchOS 7.0, *)
public final class ImageManager : ObservableObject {
/// loaded image, note when progressive loading, this will published multiple times with different partial image
@Published public var image: PlatformImage?
public var image: PlatformImage? {
didSet {
DispatchQueue.main.async {
self.objectWillChange.send()
}
}
}
/// loaded image data, may be nil if hit from memory cache. This will only published once even on incremental image loading
@Published public var imageData: Data?
public var imageData: Data? {
didSet {
DispatchQueue.main.async {
self.objectWillChange.send()
}
}
}
/// loaded image cache type, .none means from network
@Published public var cacheType: SDImageCacheType = .none
public var cacheType: SDImageCacheType = .none {
didSet {
DispatchQueue.main.async {
self.objectWillChange.send()
}
}
}
/// loading error, you can grab the error code and reason listed in `SDWebImageErrorDomain`, to provide a user interface about the error reason
@Published public var error: Error?
public var error: Error? {
didSet {
DispatchQueue.main.async {
self.objectWillChange.send()
}
}
}
/// true means during incremental loading
@Published public var isIncremental: Bool = false
public var isIncremental: Bool = false {
didSet {
DispatchQueue.main.async {
self.objectWillChange.send()
}
}
}
/// A observed object to pass through the image manager loading status to indicator
@Published public var indicatorStatus = IndicatorStatus()
public var indicatorStatus = IndicatorStatus()

weak var currentOperation: SDWebImageOperation? = nil

Expand All @@ -51,8 +81,8 @@ public final class ImageManager : ObservableObject {
return
}
currentURL = url
indicatorStatus.isLoading = true
indicatorStatus.progress = 0
self.indicatorStatus.isLoading = true
self.indicatorStatus.progress = 0
currentOperation = manager.loadImage(with: url, options: options, context: context, progress: { [weak self] (receivedSize, expectedSize, _) in
guard let self = self else {
return
Expand All @@ -63,9 +93,7 @@ public final class ImageManager : ObservableObject {
} else {
progress = 0
}
DispatchQueue.main.async {
self.indicatorStatus.progress = progress
}
self.indicatorStatus.progress = progress
self.progressBlock?(receivedSize, expectedSize)
}) { [weak self] (image, data, error, cacheType, finished, _) in
guard let self = self else {
Expand Down
16 changes: 14 additions & 2 deletions SDWebImageSwiftUI/Classes/Indicator/Indicator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,21 @@ public struct Indicator<T> where T : View {
@available(iOS 14.0, OSX 11.0, tvOS 14.0, watchOS 7.0, *)
public class IndicatorStatus : ObservableObject {
/// whether indicator is loading or not
@Published var isLoading: Bool = false
var isLoading: Bool = false {
didSet {
DispatchQueue.main.async {
self.objectWillChange.send()
}
}
}
/// indicator progress, should only be used for indicator binding, value between [0.0, 1.0]
@Published var progress: Double = 0
var progress: Double = 0 {
didSet {
DispatchQueue.main.async {
self.objectWillChange.send()
}
}
}
}

/// A implementation detail View Modifier with indicator
Expand Down
92 changes: 0 additions & 92 deletions SDWebImageSwiftUI/Classes/SwiftUICompatibility.swift

This file was deleted.

24 changes: 15 additions & 9 deletions SDWebImageSwiftUI/Classes/WebImage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -163,26 +163,22 @@ public struct WebImage<Content> : View where Content: View {
}
} else {
content((imageManager.error != nil) ? .failure(imageManager.error!) : .empty)
setupPlaceholder()
setupInitialState()
// Load Logic
.onPlatformAppear(appear: {
self.setupManager()
if (self.imageManager.error == nil) {
// Load remote image when first appear
self.imageManager.load(url: imageModel.url, options: imageModel.options, context: imageModel.context)
}
.onAppear {
guard self.imageConfiguration.retryOnAppear else { return }
// When using prorgessive loading, the new partial image will cause onAppear. Filter this case
if self.imageManager.error != nil && !self.imageManager.isIncremental {
self.imageManager.load(url: imageModel.url, options: imageModel.options, context: imageModel.context)
}
}, disappear: {
}
.onDisappear {
guard self.imageConfiguration.cancelOnDisappear else { return }
// When using prorgessive loading, the previous partial image will cause onDisappear. Filter this case
if self.imageManager.error != nil && !self.imageManager.isIncremental {
self.imageManager.cancel()
}
})
}
}
}
}
Expand Down Expand Up @@ -328,6 +324,16 @@ public struct WebImage<Content> : View where Content: View {
}
}

/// Initial state management (update when imageModel.url changed)
func setupInitialState() -> some View {
self.setupManager()
if (self.imageManager.error == nil) {
// Load remote image when first appear
self.imageManager.load(url: imageModel.url, options: imageModel.options, context: imageModel.context)
}
return setupPlaceholder()
}

/// Placeholder View Support
func setupPlaceholder() -> some View {
let result = content((imageManager.error != nil) ? .failure(imageManager.error!) : .empty)
Expand Down

0 comments on commit c5f6404

Please sign in to comment.