From 72c7c8d693c83d4717a4e614ba4fecb65d985bfc Mon Sep 17 00:00:00 2001 From: DreamPiggy Date: Tue, 24 Mar 2020 18:47:35 +0800 Subject: [PATCH] Change the API of completionHandler for ImageManager, without return value. Add test cases --- .../SDWebImageSwiftUIDemo/ContentView.swift | 2 +- SDWebImageSwiftUI.xcodeproj/project.pbxproj | 8 ++++ SDWebImageSwiftUI/Classes/ImageManager.swift | 15 +++---- Tests/ImageManagerTests.swift | 43 +++++++++++++++++++ Tests/TestUtils.swift | 2 +- 5 files changed, 59 insertions(+), 11 deletions(-) create mode 100644 Tests/ImageManagerTests.swift diff --git a/Example/SDWebImageSwiftUIDemo/ContentView.swift b/Example/SDWebImageSwiftUIDemo/ContentView.swift index 6399473..8cae887 100644 --- a/Example/SDWebImageSwiftUIDemo/ContentView.swift +++ b/Example/SDWebImageSwiftUIDemo/ContentView.swift @@ -54,7 +54,7 @@ struct ContentView: View { "https://www.sample-videos.com/img/Sample-png-image-1mb.png", "https://nr-platform.s3.amazonaws.com/uploads/platform/published_extension/branding_icon/275/AmazonS3.png", "https://raw.githubusercontent.com/ibireme/YYImage/master/Demo/YYImageDemo/mew_baseline.jpg", - "http://via.placeholder.com/200x200.jpg", + "https://via.placeholder.com/200x200.jpg", "https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/w3c.svg", "https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/wikimedia.svg", "https://raw.githubusercontent.com/icons8/flat-color-icons/master/pdf/stack_of_photos.pdf", diff --git a/SDWebImageSwiftUI.xcodeproj/project.pbxproj b/SDWebImageSwiftUI.xcodeproj/project.pbxproj index bded687..359251c 100644 --- a/SDWebImageSwiftUI.xcodeproj/project.pbxproj +++ b/SDWebImageSwiftUI.xcodeproj/project.pbxproj @@ -79,6 +79,9 @@ 32C43E3322FD5DF400BE87F5 /* SDWebImageSwiftUI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32C43E3122FD5DE100BE87F5 /* SDWebImageSwiftUI.swift */; }; 32C43E3422FD5DF400BE87F5 /* SDWebImageSwiftUI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32C43E3122FD5DE100BE87F5 /* SDWebImageSwiftUI.swift */; }; 32C43E3522FD5DF400BE87F5 /* SDWebImageSwiftUI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32C43E3122FD5DE100BE87F5 /* SDWebImageSwiftUI.swift */; }; + 32ED4826242A13030053338E /* ImageManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32ED4825242A13030053338E /* ImageManagerTests.swift */; }; + 32ED4827242A13030053338E /* ImageManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32ED4825242A13030053338E /* ImageManagerTests.swift */; }; + 32ED4828242A13030053338E /* ImageManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32ED4825242A13030053338E /* ImageManagerTests.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -181,6 +184,7 @@ 32C43E2922FD586200BE87F5 /* SDWebImage.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDWebImage.framework; path = Carthage/Build/tvOS/SDWebImage.framework; sourceTree = ""; }; 32C43E2D22FD586E00BE87F5 /* SDWebImage.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDWebImage.framework; path = Carthage/Build/watchOS/SDWebImage.framework; sourceTree = ""; }; 32C43E3122FD5DE100BE87F5 /* SDWebImageSwiftUI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SDWebImageSwiftUI.swift; sourceTree = ""; }; + 32ED4825242A13030053338E /* ImageManagerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageManagerTests.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -257,6 +261,7 @@ 3211F84623DE984D00FC757F /* AnimatedImageTests.swift */, 3211F84F23DE98E300FC757F /* WebImageTests.swift */, 32BD9C4623E03B08008D5F6A /* IndicatorTests.swift */, + 32ED4825242A13030053338E /* ImageManagerTests.swift */, 322E0F4723E57F09006836DC /* TestUtils.swift */, ); path = Tests; @@ -707,6 +712,7 @@ 32BD9C4723E03B08008D5F6A /* IndicatorTests.swift in Sources */, 3211F84723DE984D00FC757F /* AnimatedImageTests.swift in Sources */, 322E0F4823E57F09006836DC /* TestUtils.swift in Sources */, + 32ED4826242A13030053338E /* ImageManagerTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -718,6 +724,7 @@ 32BD9C4823E03B08008D5F6A /* IndicatorTests.swift in Sources */, 321C1D6A23DEDB98009CF62A /* AnimatedImageTests.swift in Sources */, 322E0F4923E57F09006836DC /* TestUtils.swift in Sources */, + 32ED4827242A13030053338E /* ImageManagerTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -729,6 +736,7 @@ 32BD9C4923E03B08008D5F6A /* IndicatorTests.swift in Sources */, 321C1D6C23DEDB98009CF62A /* AnimatedImageTests.swift in Sources */, 322E0F4A23E57F09006836DC /* TestUtils.swift in Sources */, + 32ED4828242A13030053338E /* ImageManagerTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/SDWebImageSwiftUI/Classes/ImageManager.swift b/SDWebImageSwiftUI/Classes/ImageManager.swift index eccb21d..7726769 100644 --- a/SDWebImageSwiftUI/Classes/ImageManager.swift +++ b/SDWebImageSwiftUI/Classes/ImageManager.swift @@ -15,6 +15,8 @@ import SDWebImage 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? + /// 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? /// whether network is loading or cache is querying, should only be used for indicator binding @Published public var isLoading: Bool = false /// network progress, should only be used for indicator binding @@ -81,6 +83,7 @@ public final class ImageManager : ObservableObject { return } self.image = image + self.error = error self.isIncremental = !finished if finished { self.isLoading = false @@ -110,28 +113,22 @@ extension ImageManager { /// Provide the action when image load fails. /// - Parameters: /// - action: The action to perform. The first arg is the error during loading. If `action` is `nil`, the call has no effect. - /// - Returns: A view that triggers `action` when this image load fails. - public func onFailure(perform action: ((Error) -> Void)? = nil) -> ImageManager { + public func setOnFailure(perform action: ((Error) -> Void)? = nil) { self.failureBlock = action - return self } /// Provide the action when image load successes. /// - Parameters: /// - action: The action to perform. The first arg is the loaded image, the second arg is the cache type loaded from. If `action` is `nil`, the call has no effect. - /// - Returns: A view that triggers `action` when this image load successes. - public func onSuccess(perform action: ((PlatformImage, SDImageCacheType) -> Void)? = nil) -> ImageManager { + public func setOnSuccess(perform action: ((PlatformImage, SDImageCacheType) -> Void)? = nil) { self.successBlock = action - return self } /// Provide the action when image load progress changes. /// - Parameters: /// - action: The action to perform. The first arg is the received size, the second arg is the total size, all in bytes. If `action` is `nil`, the call has no effect. - /// - Returns: A view that triggers `action` when this image load successes. - public func onProgress(perform action: ((Int, Int) -> Void)? = nil) -> ImageManager { + public func setOnProgress(perform action: ((Int, Int) -> Void)? = nil) { self.progressBlock = action - return self } } diff --git a/Tests/ImageManagerTests.swift b/Tests/ImageManagerTests.swift new file mode 100644 index 0000000..44173c0 --- /dev/null +++ b/Tests/ImageManagerTests.swift @@ -0,0 +1,43 @@ +import XCTest +import SwiftUI +import ViewInspector +@testable import SDWebImageSwiftUI + +class ImageManagerTests: XCTestCase { + + override func setUp() { + super.setUp() + // Put setup code here. This method is called before the invocation of each test method in the class. + } + + override func tearDown() { + // Put teardown code here. This method is called after the invocation of each test method in the class. + super.tearDown() + } + + func testImageManager() throws { + let expectation = self.expectation(description: "ImageManager usage with Combine") + let imageUrl = URL(string: "https://via.placeholder.com/500x500.jpg") + let imageManager = ImageManager(url: imageUrl) + imageManager.setOnSuccess { image, cacheType in + XCTAssertNotNil(image) + expectation.fulfill() + } + imageManager.setOnFailure { error in + XCTFail() + } + imageManager.setOnProgress { receivedSize, expectedSize in + + } + imageManager.load() + XCTAssertNotNil(imageManager.currentOperation) + let sub = imageManager.objectWillChange + .subscribe(on: RunLoop.main) + .receive(on: RunLoop.main) + .sink { value in + print(value) + } + sub.cancel() + self.waitForExpectations(timeout: 5, handler: nil) + } +} diff --git a/Tests/TestUtils.swift b/Tests/TestUtils.swift index 661d119..04ad86d 100644 --- a/Tests/TestUtils.swift +++ b/Tests/TestUtils.swift @@ -3,7 +3,7 @@ import SwiftUI import ViewInspector @testable import SDWebImageSwiftUI -public extension PlatformViewRepresentable where Self: Inspectable { +extension PlatformViewRepresentable where Self: Inspectable { func platformView() throws -> PlatformViewType { #if os(macOS)