Skip to content

Supports onSuccess/onFailure/onProgress callback for WebImage/AnimatedImage #10

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Oct 3, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Example/SDWebImageSwiftUI.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
320CDC3222FADB45007CF858 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 320CDC3122FADB45007CF858 /* Assets.xcassets */; };
320CDC3522FADB45007CF858 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 320CDC3422FADB45007CF858 /* Preview Assets.xcassets */; };
320CDC3822FADB45007CF858 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 320CDC3622FADB45007CF858 /* LaunchScreen.storyboard */; };
321A6BF02345EC4E00B5BEFC /* ProgressBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 321A6BEF2345EC4E00B5BEFC /* ProgressBar.swift */; };
326B0D712345C01900D28269 /* DetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 326B0D702345C01900D28269 /* DetailView.swift */; };
CECA1658ECBAF54E3FF3EF58 /* Pods_SDWebImageSwiftUIDemo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4A371F81C3B5BD6972F7A0E2 /* Pods_SDWebImageSwiftUIDemo.framework */; };
/* End PBXBuildFile section */
Expand All @@ -28,6 +29,7 @@
320CDC3422FADB45007CF858 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = "<group>"; };
320CDC3722FADB45007CF858 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
320CDC3922FADB45007CF858 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
321A6BEF2345EC4E00B5BEFC /* ProgressBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProgressBar.swift; sourceTree = "<group>"; };
326B0D702345C01900D28269 /* DetailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DetailView.swift; sourceTree = "<group>"; };
3E9F8B5F06960FFFBD1A5F99 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = "<group>"; };
4A371F81C3B5BD6972F7A0E2 /* Pods_SDWebImageSwiftUIDemo.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_SDWebImageSwiftUIDemo.framework; sourceTree = BUILT_PRODUCTS_DIR; };
Expand Down Expand Up @@ -70,6 +72,7 @@
320CDC2D22FADB44007CF858 /* SceneDelegate.swift */,
320CDC2F22FADB44007CF858 /* ContentView.swift */,
326B0D702345C01900D28269 /* DetailView.swift */,
321A6BEF2345EC4E00B5BEFC /* ProgressBar.swift */,
320CDC3122FADB45007CF858 /* Assets.xcassets */,
320CDC3622FADB45007CF858 /* LaunchScreen.storyboard */,
320CDC3922FADB45007CF858 /* Info.plist */,
Expand Down Expand Up @@ -268,6 +271,7 @@
320CDC2C22FADB44007CF858 /* AppDelegate.swift in Sources */,
326B0D712345C01900D28269 /* DetailView.swift in Sources */,
320CDC2E22FADB44007CF858 /* SceneDelegate.swift in Sources */,
321A6BF02345EC4E00B5BEFC /* ProgressBar.swift in Sources */,
320CDC3022FADB44007CF858 /* ContentView.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down
43 changes: 34 additions & 9 deletions Example/SDWebImageSwiftUIDemo/DetailView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,43 @@ import SDWebImageSwiftUI
struct DetailView: View {
let url: String
let animated: Bool
@State var progress: CGFloat = 1

var body: some View {
Group {
if animated {
AnimatedImage(url: URL(string:url), options: [.progressiveLoad])
.resizable()
.scaledToFit()
} else {
WebImage(url: URL(string:url), options: [.progressiveLoad])
.resizable()
.scaledToFit()
VStack {
HStack {
ProgressBar(value: $progress)
.foregroundColor(.blue)
.frame(maxHeight: 6)
}
Spacer()
HStack {
if animated {
AnimatedImage(url: URL(string:url), options: [.progressiveLoad])
.onProgress(perform: { (receivedSize, expectedSize) in
// SwiftUI engine itself ensure the main queue dispatch
if (expectedSize >= 0) {
self.progress = CGFloat(receivedSize) / CGFloat(expectedSize)
} else {
self.progress = 1
}
})
.resizable()
.scaledToFit()
} else {
WebImage(url: URL(string:url), options: [.progressiveLoad])
.onProgress(perform: { (receivedSize, expectedSize) in
if (expectedSize >= 0) {
self.progress = CGFloat(receivedSize) / CGFloat(expectedSize)
} else {
self.progress = 1
}
})
.resizable()
.scaledToFit()
}
}
Spacer()
}
}
}
Expand Down
28 changes: 28 additions & 0 deletions Example/SDWebImageSwiftUIDemo/ProgressBar.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* This file is part of the SDWebImage package.
* (c) DreamPiggy <lizhuoli1126@126.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

import SwiftUI

/// A linear view that depicts the progress of a task over time.
public struct ProgressBar: View {
@Binding var value: CGFloat

public var body: some View {
GeometryReader { geometry in
ZStack(alignment: .topLeading) {
Capsule()
.frame(width: geometry.size.width)
.opacity(0.3)
Rectangle()
.frame(width: geometry.size.width * self.value)
}
}
.clipShape(Capsule())
.opacity(self.value < 1 ? 1 : 0)
}
}
47 changes: 35 additions & 12 deletions SDWebImageSwiftUI/Classes/AnimatedImage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ import SDWebImage
final class AnimatedImageModel : ObservableObject {
@Published var image: PlatformImage?
@Published var url: URL?
@Published var successBlock: ((PlatformImage, SDImageCacheType) -> Void)?
@Published var failureBlock: ((Error) -> Void)?
@Published var progressBlock: ((Int, Int) -> Void)?
}

// Layout Binding Object
Expand Down Expand Up @@ -67,7 +70,15 @@ public struct AnimatedImage : ViewRepresentable {
func updateView(_ view: AnimatedImageViewWrapper, context: ViewRepresentableContext<AnimatedImage>) {
view.wrapped.image = imageModel.image
if let url = imageModel.url {
view.wrapped.sd_setImage(with: url, placeholderImage: nil, options: webOptions, context: webContext)
view.wrapped.sd_setImage(with: url, placeholderImage: nil, options: webOptions, context: webContext, progress: { (receivedSize, expectedSize, _) in
self.imageModel.progressBlock?(receivedSize, expectedSize)
}) { (image, error, cacheType, _) in
if let image = image {
self.imageModel.successBlock?(image, cacheType)
} else {
self.imageModel.failureBlock?(error ?? NSError())
}
}
}

layoutView(view, context: context)
Expand Down Expand Up @@ -178,17 +189,10 @@ public struct AnimatedImage : ViewRepresentable {
view.setNeedsDisplay()
#endif
}

public func image(_ image: PlatformImage?) -> Self {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wrong API design. The WebImage and AnimatedImage should be immutable struct. If we want to change image, refresh the View Tree to provide another struct. Just like SwiftUI's tutorial or some other declarative framework (Flutter, React for example)

imageModel.image = image
return self
}

public func imageUrl(_ url: URL?) -> Self {
imageModel.url = url
return self
}

}

// Layout
extension AnimatedImage {
public func resizable(
capInsets: EdgeInsets = EdgeInsets(),
resizingMode: Image.ResizingMode = .stretch) -> AnimatedImage
Expand Down Expand Up @@ -236,6 +240,25 @@ public struct AnimatedImage : ViewRepresentable {
}
}

// Completion Handler
extension AnimatedImage {
public func onFailure(perform action: ((Error) -> Void)? = nil) -> AnimatedImage {
imageModel.failureBlock = action
return self
}

public func onSuccess(perform action: ((PlatformImage, SDImageCacheType) -> Void)? = nil) -> AnimatedImage {
imageModel.successBlock = action
return self
}

public func onProgress(perform action: ((Int, Int) -> Void)? = nil) -> AnimatedImage {
imageModel.progressBlock = action
return self
}
}

// Initializer
extension AnimatedImage {
public init(url: URL?, placeholder: PlatformImage? = nil, options: SDWebImageOptions = [], context: [SDWebImageContextOption : Any]? = nil) {
self.webOptions = options
Expand Down
13 changes: 12 additions & 1 deletion SDWebImageSwiftUI/Classes/ImageManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ class ImageManager : ObservableObject {
var url: URL?
var options: SDWebImageOptions
var context: [SDWebImageContextOption : Any]?
var successBlock: ((PlatformImage, SDImageCacheType) -> Void)?
var failureBlock: ((Error) -> Void)?
var progressBlock: ((Int, Int) -> Void)?

init(url: URL?, options: SDWebImageOptions = [], context: [SDWebImageContextOption : Any]? = nil) {
self.url = url
Expand All @@ -34,9 +37,17 @@ class ImageManager : ObservableObject {
}

func load() {
currentOperation = manager.loadImage(with: url, options: options, context: context, progress: nil) { (image, data, error, cacheType, _, _) in
currentOperation = manager.loadImage(with: url, options: options, context: context, progress: { [weak self] (receivedSize, expectedSize, _) in
self?.progressBlock?(receivedSize, expectedSize)
}) { [weak self] (image, data, error, cacheType, _, _) in
guard let self = self else {
return
}
if let image = image {
self.image = image
self.successBlock?(image, cacheType)
} else {
self.failureBlock?(error ?? NSError())
}
}
}
Expand Down
18 changes: 18 additions & 0 deletions SDWebImageSwiftUI/Classes/WebImage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ public struct WebImage : View {
}
}

// Layout
extension WebImage {
func configure(_ block: @escaping (Image) -> Image) -> WebImage {
var result = self
Expand Down Expand Up @@ -82,6 +83,23 @@ extension WebImage {
}
}

// Completion Handler
extension WebImage {
public func onFailure(perform action: ((Error) -> Void)? = nil) -> WebImage {
self.imageManager.failureBlock = action
return self
}

public func onSuccess(perform action: ((PlatformImage, SDImageCacheType) -> Void)? = nil) -> WebImage {
self.imageManager.successBlock = action
return self
}

public func onProgress(perform action: ((Int, Int) -> Void)? = nil) -> WebImage {
self.imageManager.progressBlock = action
return self
}
}

#if DEBUG
struct WebImage_Previews : PreviewProvider {
Expand Down