Browse Source

Concept proving for SwiftUI support

onevcat 6 years ago
parent
commit
797727b776

+ 8 - 0
.swiftpm/xcode/package.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>IDEDidComputeMac32BitWarning</key>
+	<true/>
+</dict>
+</plist>

+ 13 - 14
Demo/Demo/Kingfisher-Demo/ViewControllers/SwiftUIView.swift

@@ -24,22 +24,21 @@
 //  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 //  THE SOFTWARE.
 
+import Kingfisher
 import SwiftUI
 
-@available(iOS 13.0, *)
-struct KFImage: View {
-
-    @ObjectBinding var image: UIImage
-
-    var body: some View {
-        Image(uiImage: image)
-    }
-}
-
-@available(iOS 13.0, *)
-struct SwiftUIView : View {
-    var body: some View {
-        Text("Hello World!")
+@available(iOS 13.0, OSX 10.15, tvOS 13.0, watchOS 6.0, *)
+struct SwiftUIView : SwiftUI.View {
+    var body: some SwiftUI.View {
+        VStack {
+            Text("Hello World")
+            KFImage(url: URL(string: "https://onevcat.com/assets/images/avatar.jpg")!)
+                .resizable()
+                .padding()
+                .background(Color.red)
+                .frame(width: 400, height: 400)
+            Text("Test Me")
+        }
     }
 }
 

+ 0 - 27
Demo/Demo/Kingfisher-Demo/ViewControllers/SwiftUIViewController.swift

@@ -1,27 +0,0 @@
-//
-//  SwiftUIViewController.swift
-//  Kingfisher
-//
-//  Created by Wei Wang on 2019/06/18.
-//
-//  Copyright (c) 2019 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 Foundation

+ 0 - 4
Demo/Kingfisher-Demo.xcodeproj/project.pbxproj

@@ -16,7 +16,6 @@
 		4B4307A51D87E6A700ED2DA9 /* loader.gif in Resources */ = {isa = PBXBuildFile; fileRef = 4B7742461D87E42E0077024E /* loader.gif */; };
 		4B7742471D87E42E0077024E /* loader.gif in Resources */ = {isa = PBXBuildFile; fileRef = 4B7742461D87E42E0077024E /* loader.gif */; };
 		4B7742481D87E42E0077024E /* loader.gif in Resources */ = {isa = PBXBuildFile; fileRef = 4B7742461D87E42E0077024E /* loader.gif */; };
-		4B91BFB222B8D45000FDC81F /* SwiftUIViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B91BFB122B8D45000FDC81F /* SwiftUIViewController.swift */; };
 		4BB3DE8622B8D9C400F65D51 /* SwiftUIView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BB3DE8522B8D9C400F65D51 /* SwiftUIView.swift */; };
 		4BCCF33D1D5B02F8003387C2 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BCCF3361D5B02F8003387C2 /* AppDelegate.swift */; };
 		4BCCF33E1D5B02F8003387C2 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4BCCF3371D5B02F8003387C2 /* Assets.xcassets */; };
@@ -144,7 +143,6 @@
 		4B1C7A3C21A256E300CE9D31 /* InfinityCollectionViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InfinityCollectionViewController.swift; sourceTree = "<group>"; };
 		4B2944551C3D03880088C3E7 /* Kingfisher-macOS-Demo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Kingfisher-macOS-Demo.app"; sourceTree = BUILT_PRODUCTS_DIR; };
 		4B7742461D87E42E0077024E /* loader.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = loader.gif; sourceTree = "<group>"; };
-		4B91BFB122B8D45000FDC81F /* SwiftUIViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SwiftUIViewController.swift; sourceTree = "<group>"; };
 		4BB3DE8522B8D9C400F65D51 /* SwiftUIView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SwiftUIView.swift; sourceTree = "<group>"; };
 		4BCCF3361D5B02F8003387C2 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
 		4BCCF3371D5B02F8003387C2 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
@@ -328,7 +326,6 @@
 			children = (
 				4BB3DE8522B8D9C400F65D51 /* SwiftUIView.swift */,
 				D1A1CCA221A1879600263AD8 /* MainViewController.swift */,
-				4B91BFB122B8D45000FDC81F /* SwiftUIViewController.swift */,
 				D10AC99721A300C9005F057C /* ProcessorCollectionViewController.swift */,
 				4B1C7A3C21A256E300CE9D31 /* InfinityCollectionViewController.swift */,
 				D1CE1BCF21A1AFA300419000 /* TransitionViewController.swift */,
@@ -617,7 +614,6 @@
 			isa = PBXSourcesBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
-				4B91BFB222B8D45000FDC81F /* SwiftUIViewController.swift in Sources */,
 				C959EEE622874DC600467A10 /* ProgressiveJPEGViewController.swift in Sources */,
 				4BB3DE8622B8D9C400F65D51 /* SwiftUIView.swift in Sources */,
 				D1CE1BD321A1B45A00419000 /* ImageLoader.swift in Sources */,

+ 18 - 0
Kingfisher.xcodeproj/project.pbxproj

@@ -26,6 +26,10 @@
 		4B46CC6A21744AC500D90C4A /* DiskStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B46CC6821744AC500D90C4A /* DiskStorage.swift */; };
 		4B46CC6B21744AC500D90C4A /* DiskStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B46CC6821744AC500D90C4A /* DiskStorage.swift */; };
 		4B46CC6C21744AC500D90C4A /* DiskStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B46CC6821744AC500D90C4A /* DiskStorage.swift */; };
+		4B531FE422C35B7B0041899C /* KFImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B531FE322C35B7B0041899C /* KFImage.swift */; };
+		4B531FE522C35B7B0041899C /* KFImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B531FE322C35B7B0041899C /* KFImage.swift */; };
+		4B531FE622C35B7B0041899C /* KFImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B531FE322C35B7B0041899C /* KFImage.swift */; };
+		4B531FE722C35B7B0041899C /* KFImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B531FE322C35B7B0041899C /* KFImage.swift */; };
 		4B8351C8217066580081EED8 /* StubHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B8351C7217066580081EED8 /* StubHelpers.swift */; };
 		4B8351C9217066580081EED8 /* StubHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B8351C7217066580081EED8 /* StubHelpers.swift */; };
 		4B8351CA217066580081EED8 /* StubHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B8351C7217066580081EED8 /* StubHelpers.swift */; };
@@ -292,6 +296,7 @@
 		4B46CC5E217449C600D90C4A /* MemoryStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MemoryStorage.swift; sourceTree = "<group>"; };
 		4B46CC63217449E000D90C4A /* Storage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Storage.swift; sourceTree = "<group>"; };
 		4B46CC6821744AC500D90C4A /* DiskStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DiskStorage.swift; sourceTree = "<group>"; };
+		4B531FE322C35B7B0041899C /* KFImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = KFImage.swift; path = Sources/SwiftUI/KFImage.swift; sourceTree = "<group>"; };
 		4B8351C7217066580081EED8 /* StubHelpers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StubHelpers.swift; sourceTree = "<group>"; };
 		4B8351CB217084660081EED8 /* Runtime.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Runtime.swift; sourceTree = "<group>"; };
 		4B8E2916216F3F7F0095FAD1 /* ImageDownloaderDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageDownloaderDelegate.swift; sourceTree = "<group>"; };
@@ -434,6 +439,13 @@
 /* End PBXFrameworksBuildPhase section */
 
 /* Begin PBXGroup section */
+		4B531FE222C35B5F0041899C /* SwiftUI */ = {
+			isa = PBXGroup;
+			children = (
+			);
+			path = SwiftUI;
+			sourceTree = "<group>";
+		};
 		4B8351C6217066400081EED8 /* Utils */ = {
 			isa = PBXGroup;
 			children = (
@@ -477,6 +489,7 @@
 		D12AB688215D2A280013BA68 /* Sources */ = {
 			isa = PBXGroup;
 			children = (
+				4B531FE222C35B5F0041899C /* SwiftUI */,
 				D12AB6A9215D2BB50013BA68 /* Info.plist */,
 				D12AB6AA215D2BB50013BA68 /* Kingfisher.h */,
 				D12AB6B0215D2BB50013BA68 /* General */,
@@ -638,6 +651,7 @@
 		D1ED2D021AD2CFA600CFC3EB = {
 			isa = PBXGroup;
 			children = (
+				4B531FE322C35B7B0041899C /* KFImage.swift */,
 				D12AB688215D2A280013BA68 /* Sources */,
 				D10EC22C1C3D62E800A4211C /* Tests */,
 				D1ED2D0C1AD2CFA600CFC3EB /* Products */,
@@ -1109,6 +1123,7 @@
 				C9286409228584EB00257182 /* ImageProgressive.swift in Sources */,
 				4BD821642189FC0C0084CC21 /* SessionDelegate.swift in Sources */,
 				D1A37BD6215D2DBA009B39B7 /* Resource.swift in Sources */,
+				4B531FE622C35B7B0041899C /* KFImage.swift in Sources */,
 				D1A37BD7215D2DBA009B39B7 /* ImageDownloader.swift in Sources */,
 				D1A37BD8215D2DBA009B39B7 /* ImageModifier.swift in Sources */,
 				D1A37BD9215D2DBA009B39B7 /* ImagePrefetcher.swift in Sources */,
@@ -1178,6 +1193,7 @@
 				D12AB719215D2BB50013BA68 /* CacheSerializer.swift in Sources */,
 				D1E56446219B16330057AAE3 /* ImageDataProvider.swift in Sources */,
 				D12AB731215D2BB50013BA68 /* AnimatedImageView.swift in Sources */,
+				4B531FE522C35B7B0041899C /* KFImage.swift in Sources */,
 				4B46CC65217449E000D90C4A /* Storage.swift in Sources */,
 				D12AB6E5215D2BB50013BA68 /* Placeholder.swift in Sources */,
 				4B46CC6A21744AC500D90C4A /* DiskStorage.swift in Sources */,
@@ -1233,6 +1249,7 @@
 				D12AB71B215D2BB50013BA68 /* CacheSerializer.swift in Sources */,
 				4B46CC6C21744AC500D90C4A /* DiskStorage.swift in Sources */,
 				D8B3692821C5CED6000F36F6 /* RedirectHandler.swift in Sources */,
+				4B531FE722C35B7B0041899C /* KFImage.swift in Sources */,
 				D12AB6DB215D2BB50013BA68 /* ImageTransition.swift in Sources */,
 				4BD821652189FC0C0084CC21 /* SessionDelegate.swift in Sources */,
 				D1BA78202174D07800C69D7B /* CallbackQueue.swift in Sources */,
@@ -1277,6 +1294,7 @@
 				D12AB718215D2BB50013BA68 /* CacheSerializer.swift in Sources */,
 				D1E56445219B16330057AAE3 /* ImageDataProvider.swift in Sources */,
 				D12AB730215D2BB50013BA68 /* AnimatedImageView.swift in Sources */,
+				4B531FE422C35B7B0041899C /* KFImage.swift in Sources */,
 				4B46CC64217449E000D90C4A /* Storage.swift in Sources */,
 				D12AB6E4215D2BB50013BA68 /* Placeholder.swift in Sources */,
 				4B46CC6921744AC500D90C4A /* DiskStorage.swift in Sources */,

+ 93 - 0
Sources/SwiftUI/KFImage.swift

@@ -0,0 +1,93 @@
+//
+//  KFImage.swift
+//  Kingfisher
+//
+//  Created by jp20028 on 2019/06/26.
+//
+//  Copyright (c) 2019 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
+import Kingfisher
+import Combine
+
+@available(iOS 13.0, OSX 10.15, tvOS 13.0, watchOS 6.0, *)
+class ImageBinder: BindableObject {
+    let url: URL
+    var didChange = PassthroughSubject<Kingfisher.Image?, Never>()
+
+    var image: Kingfisher.Image? {
+        didSet {
+            didChange.send(image)
+        }
+    }
+
+    init(url: URL) {
+        self.url = url
+        _ = KingfisherManager.shared.retrieveImage(with: .network(url)) { r in
+            switch r {
+            case .success(let result): self.image = result.image
+            case .failure(let error): break
+            }
+        }
+    }
+}
+
+@available(iOS 13.0, OSX 10.15, tvOS 13.0, watchOS 6.0, *)
+public struct KFImage: SwiftUI.View {
+
+    static let empty = Kingfisher.Image()
+
+    private var capInsets: EdgeInsets?
+    private var resizingMode: SwiftUI.Image.ResizingMode?
+
+    var config: [(SwiftUI.Image) -> SwiftUI.Image]
+
+    @ObjectBinding var binder: ImageBinder
+
+    public init(url: URL) {
+        binder = ImageBinder(url: url)
+        config = []
+    }
+
+    public var body: some SwiftUI.View {
+        #if canImport(UIKit)
+        let image = SwiftUI.Image(uiImage: binder.image ?? KFImage.empty)
+        #elseif canImport(AppKit)
+        let image = SwiftUI.Image(nsImage: binder.image ?? KFImage.empty)
+        #endif
+
+        return config.reduce(image) { current, config in config(current) }
+    }
+
+    public func resizable(capInsets: EdgeInsets = EdgeInsets(), resizingMode: SwiftUI.Image.ResizingMode = .stretch) -> KFImage {
+        var result = self
+        result.config.append { $0.resizable(capInsets: capInsets, resizingMode: resizingMode) }
+        return result
+    }
+}
+
+#if DEBUG
+struct KFImage_Previews : PreviewProvider {
+    static var previews: some View {
+        KFImage()
+    }
+}
+#endif