onevcat 5 лет назад
Родитель
Сommit
b3841c1021

+ 4 - 0
Kingfisher.xcodeproj/project.pbxproj

@@ -91,6 +91,7 @@
 		D16FEA5523079707006E67D5 /* NSButtonExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 185218B51CC07F8300BD58DE /* NSButtonExtensionTests.swift */; };
 		D1839845216E333E003927D3 /* Delegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1839844216E333E003927D3 /* Delegate.swift */; };
 		D186696D21834261002B502E /* ImageDrawingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D186696C21834261002B502E /* ImageDrawingTests.swift */; };
+		D1889534258F7649003B73BE /* KFImageOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1889533258F7648003B73BE /* KFImageOptions.swift */; };
 		D18B3222251852E100662F63 /* KF.swift in Sources */ = {isa = PBXBuildFile; fileRef = D18B3221251852E100662F63 /* KF.swift */; };
 		D1A1CC9A219FAB4B00263AD8 /* Source.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1A1CC99219FAB4B00263AD8 /* Source.swift */; };
 		D1A1CC9F21A0F98600263AD8 /* ImageDataProviderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1A1CC9E21A0F98600263AD8 /* ImageDataProviderTests.swift */; };
@@ -245,6 +246,7 @@
 		D16FEA3923078C63006E67D5 /* LSStubResponseDSL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LSStubResponseDSL.h; sourceTree = "<group>"; };
 		D1839844216E333E003927D3 /* Delegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Delegate.swift; sourceTree = "<group>"; };
 		D186696C21834261002B502E /* ImageDrawingTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageDrawingTests.swift; sourceTree = "<group>"; };
+		D1889533258F7648003B73BE /* KFImageOptions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KFImageOptions.swift; sourceTree = "<group>"; };
 		D18B3221251852E100662F63 /* KF.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KF.swift; sourceTree = "<group>"; };
 		D1A1CC99219FAB4B00263AD8 /* Source.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Source.swift; sourceTree = "<group>"; };
 		D1A1CC9E21A0F98600263AD8 /* ImageDataProviderTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageDataProviderTests.swift; sourceTree = "<group>"; };
@@ -648,6 +650,7 @@
 			children = (
 				D1F7607523097532000C5269 /* ImageBinder.swift */,
 				D1F7607623097532000C5269 /* KFImage.swift */,
+				D1889533258F7648003B73BE /* KFImageOptions.swift */,
 			);
 			path = SwiftUI;
 			sourceTree = "<group>";
@@ -803,6 +806,7 @@
 				D11D9B72245FA6F700C5A0AE /* RetryStrategy.swift in Sources */,
 				D1A37BE3215D359F009B39B7 /* ImageFormat.swift in Sources */,
 				D12EB83C24DD8EFC00329EE1 /* NSTextAttachment+Kingfisher.swift in Sources */,
+				D1889534258F7649003B73BE /* KFImageOptions.swift in Sources */,
 				D12AB714215D2BB50013BA68 /* ImageCache.swift in Sources */,
 				D12AB6D0215D2BB50013BA68 /* ImagePrefetcher.swift in Sources */,
 				D12AB6F4215D2BB50013BA68 /* ImageView+Kingfisher.swift in Sources */,

+ 17 - 0
Sources/SwiftUI/ImageBinder.swift

@@ -28,6 +28,12 @@
 import Combine
 import SwiftUI
 
+public enum KFImageLoadingState {
+    case notLoaded
+    case loaded(RetrieveImageResult)
+    case error(KingfisherError)
+}
+
 @available(iOS 13.0, OSX 10.15, tvOS 13.0, watchOS 6.0, *)
 extension KFImage {
 
@@ -47,6 +53,7 @@ extension KFImage {
         let onProgressDelegate = Delegate<(Int64, Int64), Void>()
 
         var isLoaded: Binding<Bool>
+        var loadingState: Binding<KFImageLoadingState>?
 
         @Published var image: KFCrossPlatformImage?
 
@@ -63,6 +70,16 @@ extension KFImage {
             self.image = nil
         }
 
+        init(source: Source?, loadingState: Binding<KFImageLoadingState>? = nil) {
+            self.source = source
+            self.options = KingfisherParsedOptionsInfo(
+                KingfisherManager.shared.defaultOptions + [.loadDiskFileSynchronously]
+            )
+            self.isLoaded = .constant(false)
+            self.loadingState = loadingState
+            self.image = nil
+        }
+
         func start() {
 
             guard !loadingOrSucceeded else { return }

+ 7 - 0
Sources/SwiftUI/KFImage.swift

@@ -57,6 +57,7 @@ public struct KFImage: SwiftUI.View {
     // Configurations should be performed on the image.
     var configurations: [(SwiftUI.Image) -> SwiftUI.Image]
 
+    #warning("Deprecate this.")
     /// Creates a Kingfisher compatible image view to load image from the given `Source`.
     /// - Parameter source: The image `Source` defining where to load the target image.
     /// - Parameter options: The options should be applied when loading the image.
@@ -69,6 +70,7 @@ public struct KFImage: SwiftUI.View {
         configurations = []
     }
 
+    #warning("Deprecate this.")
     /// Creates a Kingfisher compatible image view to load image from the given `Source`.
     /// - Parameter url: The image URL from where to load the target image.
     /// - Parameter options: The options should be applied when loading the image.
@@ -80,6 +82,11 @@ public struct KFImage: SwiftUI.View {
         self.init(source: url?.convertToSource(), options: options, isLoaded: isLoaded)
     }
 
+    public init(source: Source?, loadingState: Binding<KFImageLoadingState>?) {
+        binder = ImageBinder(source: source, loadingState: loadingState)
+        configurations = []
+    }
+
     /// Declares the content and behavior of this view.
     public var body: some SwiftUI.View {
         Group {

+ 66 - 0
Sources/SwiftUI/KFImageOptions.swift

@@ -0,0 +1,66 @@
+//
+//  KFImageOptions.swift
+//  Kingfisher
+//
+//  Created by onevcat on 2020/12/20.
+//
+//  Copyright (c) 2020 Wei Wang <onevcat@gmail.com>
+//
+//  Permission is hereby granted, free of charge, to any person obtaining a copy
+//  of this software and associated documentation files (the "Software"), to deal
+//  in the Software without restriction, including without limitation the rights
+//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+//  copies of the Software, and to permit persons to whom the Software is
+//  furnished to do so, subject to the following conditions:
+//
+//  The above copyright notice and this permission notice shall be included in
+//  all copies or substantial portions of the Software.
+//
+//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+//  THE SOFTWARE.
+
+import SwiftUI
+
+// MARK: - KFImage creating.
+@available(iOS 13.0, OSX 10.15, tvOS 13.0, watchOS 6.0, *)
+extension KFImage {
+    public static func source(
+        _ source: Source, loadingState: Binding<KFImageLoadingState>? = nil
+    ) -> KFImage
+    {
+        KFImage(source: source, loadingState: loadingState)
+    }
+
+    public static func resource(
+        _ resource: Resource, loadingState: Binding<KFImageLoadingState>? = nil
+    ) -> KFImage
+    {
+        .source(.network(resource), loadingState: loadingState)
+    }
+
+    public static func url(
+        _ url: URL, cacheKey: String? = nil, loadingState: Binding<KFImageLoadingState>? = nil
+    ) -> KFImage
+    {
+        source(.network(ImageResource(downloadURL: url, cacheKey: cacheKey)), loadingState: loadingState)
+    }
+
+    public static func dataProvider(
+        _ provider: ImageDataProvider, loadingState: Binding<KFImageLoadingState>? = nil
+    ) -> KFImage
+    {
+        source(.provider(provider), loadingState: loadingState)
+    }
+
+    public static func data(
+        _ data: Data, cacheKey: String, loadingState: Binding<KFImageLoadingState>? = nil
+    ) -> KFImage
+    {
+        source(.provider(RawImageDataProvider(data: data, cacheKey: cacheKey)), loadingState: loadingState)
+    }
+}