From b6c3c0dfffb004fcbad6bd8060f6526f42efd2d7 Mon Sep 17 00:00:00 2001 From: onevcat Date: Thu, 22 Jun 2023 20:43:38 +0900 Subject: [PATCH 01/11] Add visionOS as framework build target and fix errors --- Demo/Kingfisher-Demo.xcodeproj/project.pbxproj | 8 ++++++++ Kingfisher.xcodeproj/project.pbxproj | 10 ++++++++++ .../ImageSource/AVAssetImageDataProvider.swift | 16 +++++++++++++--- Sources/Image/Image.swift | 11 +++++++++++ Sources/Views/AnimatedImageView.swift | 4 ++++ Sources/Views/Indicator.swift | 2 ++ 6 files changed, 48 insertions(+), 3 deletions(-) diff --git a/Demo/Kingfisher-Demo.xcodeproj/project.pbxproj b/Demo/Kingfisher-Demo.xcodeproj/project.pbxproj index 567190ebe..c4772bb27 100644 --- a/Demo/Kingfisher-Demo.xcodeproj/project.pbxproj +++ b/Demo/Kingfisher-Demo.xcodeproj/project.pbxproj @@ -1058,7 +1058,11 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "com.onevcat.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator xros xrsimulator"; SUPPORTS_MACCATALYST = YES; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; + TARGETED_DEVICE_FAMILY = "1,2,7"; }; name = Debug; }; @@ -1074,8 +1078,12 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "com.onevcat.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator xros xrsimulator"; SUPPORTS_MACCATALYST = YES; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + TARGETED_DEVICE_FAMILY = "1,2,7"; }; name = Release; }; diff --git a/Kingfisher.xcodeproj/project.pbxproj b/Kingfisher.xcodeproj/project.pbxproj index d402dabff..907ff7e9b 100644 --- a/Kingfisher.xcodeproj/project.pbxproj +++ b/Kingfisher.xcodeproj/project.pbxproj @@ -1079,8 +1079,13 @@ PRODUCT_BUNDLE_PACKAGE_TYPE = FMWK; PRODUCT_NAME = Kingfisher; SKIP_INSTALL = YES; + SUPPORTED_PLATFORMS = "appletvos appletvsimulator iphoneos iphonesimulator macosx watchos watchsimulator xros xrsimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + TARGETED_DEVICE_FAMILY = "1,2,3,4,7"; VERSIONING_SYSTEM = "apple-generic"; }; name = Debug; @@ -1128,7 +1133,12 @@ PRODUCT_BUNDLE_PACKAGE_TYPE = FMWK; PRODUCT_NAME = Kingfisher; SKIP_INSTALL = YES; + SUPPORTED_PLATFORMS = "appletvos appletvsimulator iphoneos iphonesimulator macosx watchos watchsimulator xros xrsimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + TARGETED_DEVICE_FAMILY = "1,2,3,4,7"; VERSIONING_SYSTEM = "apple-generic"; }; name = Release; diff --git a/Sources/General/ImageSource/AVAssetImageDataProvider.swift b/Sources/General/ImageSource/AVAssetImageDataProvider.swift index d13023b81..e3795e5d7 100644 --- a/Sources/General/ImageSource/AVAssetImageDataProvider.swift +++ b/Sources/General/ImageSource/AVAssetImageDataProvider.swift @@ -124,11 +124,21 @@ public struct AVAssetImageDataProvider: ImageDataProvider { extension CGImage { var jpegData: Data? { - guard let mutableData = CFDataCreateMutable(nil, 0), - let destination = CGImageDestinationCreateWithData(mutableData, kUTTypeJPEG, 1, nil) - else { + guard let mutableData = CFDataCreateMutable(nil, 0) else { return nil } +#if os(xrOS) + guard let destination = CGImageDestinationCreateWithData( + mutableData, UTType.jpeg.identifier as CFString , 1, nil + ) else { + return nil + } +#else + guard let destination = CGImageDestinationCreateWithData(mutableData, kUTTypeJPEG, 1, nil) else { + return nil + } +#endif + CGImageDestinationAddImage(destination, self, nil) guard CGImageDestinationFinalize(destination) else { return nil } return mutableData as Data diff --git a/Sources/Image/Image.swift b/Sources/Image/Image.swift index b6419e119..3c3136bfd 100644 --- a/Sources/Image/Image.swift +++ b/Sources/Image/Image.swift @@ -42,6 +42,10 @@ import CoreImage import CoreGraphics import ImageIO +#if canImport(UniformTypeIdentifiers) +import UniformTypeIdentifiers +#endif + private var animatedImageDataKey: Void? private var imageFrameCountKey: Void? @@ -274,10 +278,17 @@ extension KingfisherWrapper where Base: KFCrossPlatformImage { /// - Returns: An `Image` object represents the animated image. It is in form of an array of image frames with a /// certain duration. `nil` if anything wrong when creating animated image. public static func animatedImage(data: Data, options: ImageCreatingOptions) -> KFCrossPlatformImage? { + #if os(xrOS) + let info: [String: Any] = [ + kCGImageSourceShouldCache as String: true, + kCGImageSourceTypeIdentifierHint as String: UTType.gif + ] + #else let info: [String: Any] = [ kCGImageSourceShouldCache as String: true, kCGImageSourceTypeIdentifierHint as String: kUTTypeGIF ] + #endif guard let imageSource = CGImageSourceCreateWithData(data as CFData, info as CFDictionary) else { return nil diff --git a/Sources/Views/AnimatedImageView.swift b/Sources/Views/AnimatedImageView.swift index 6471398b7..048950572 100644 --- a/Sources/Views/AnimatedImageView.swift +++ b/Sources/Views/AnimatedImageView.swift @@ -265,7 +265,11 @@ open class AnimatedImageView: UIImageView { private func reset() { animator = nil if let image = image, let frameSource = image.kf.frameSource { + #if os(xrOS) + let targetSize = bounds.size + #else let targetSize = bounds.scaled(UIScreen.main.scale).size + #endif let animator = Animator( frameSource: frameSource, contentMode: contentMode, diff --git a/Sources/Views/Indicator.swift b/Sources/Views/Indicator.swift index a3fa5a416..dc9bb6e8e 100644 --- a/Sources/Views/Indicator.swift +++ b/Sources/Views/Indicator.swift @@ -148,6 +148,8 @@ final class ActivityIndicator: Indicator { } else { indicatorStyle = UIActivityIndicatorView.Style.white } + #elseif os(xrOS) + indicatorStyle = UIActivityIndicatorView.Style.medium #else if #available(iOS 13.0, * ) { indicatorStyle = UIActivityIndicatorView.Style.medium From 99cecb45ffc6f3f88cc630067e598c7005aee903 Mon Sep 17 00:00:00 2001 From: onevcat Date: Thu, 22 Jun 2023 20:46:29 +0900 Subject: [PATCH 02/11] Allow tests run on visionOS and fix failing cases --- Kingfisher.xcodeproj/project.pbxproj | 14 ++++++++++---- Sources/Image/Image.swift | 2 +- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/Kingfisher.xcodeproj/project.pbxproj b/Kingfisher.xcodeproj/project.pbxproj index 907ff7e9b..8ce37c40b 100644 --- a/Kingfisher.xcodeproj/project.pbxproj +++ b/Kingfisher.xcodeproj/project.pbxproj @@ -1156,10 +1156,13 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "com.onevcat.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; - SUPPORTED_PLATFORMS = "macosx iphoneos iphonesimulator appletvos appletvsimulator watchos watchsimulator"; + SUPPORTED_PLATFORMS = "appletvos appletvsimulator iphoneos iphonesimulator macosx watchos watchsimulator xros xrsimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; SWIFT_OBJC_BRIDGING_HEADER = "Tests/KingfisherTests/KingfisherTests-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - TARGETED_DEVICE_FAMILY = "1,2,3,4"; + TARGETED_DEVICE_FAMILY = "1,2,3,4,7"; }; name = Debug; }; @@ -1172,10 +1175,13 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "com.onevcat.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; - SUPPORTED_PLATFORMS = "macosx iphoneos iphonesimulator appletvos appletvsimulator watchos watchsimulator"; + SUPPORTED_PLATFORMS = "appletvos appletvsimulator iphoneos iphonesimulator macosx watchos watchsimulator xros xrsimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; SWIFT_OBJC_BRIDGING_HEADER = "Tests/KingfisherTests/KingfisherTests-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - TARGETED_DEVICE_FAMILY = "1,2,3,4"; + TARGETED_DEVICE_FAMILY = "1,2,3,4,7"; }; name = Release; }; diff --git a/Sources/Image/Image.swift b/Sources/Image/Image.swift index 3c3136bfd..57022cf0f 100644 --- a/Sources/Image/Image.swift +++ b/Sources/Image/Image.swift @@ -281,7 +281,7 @@ extension KingfisherWrapper where Base: KFCrossPlatformImage { #if os(xrOS) let info: [String: Any] = [ kCGImageSourceShouldCache as String: true, - kCGImageSourceTypeIdentifierHint as String: UTType.gif + kCGImageSourceTypeIdentifierHint as String: UTType.gif.identifier ] #else let info: [String: Any] = [ From 2edd31ad7ef54a837b50fa29844aeec1b334b3f0 Mon Sep 17 00:00:00 2001 From: onevcat Date: Thu, 22 Jun 2023 21:15:40 +0900 Subject: [PATCH 03/11] Set default bg color to main scene To make the sample app background visible on visionOS --- .../Base.lproj/Main.storyboard | 62 +++++++++---------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/Demo/Demo/Kingfisher-Demo/Base.lproj/Main.storyboard b/Demo/Demo/Kingfisher-Demo/Base.lproj/Main.storyboard index 8b1869018..d6324938e 100644 --- a/Demo/Demo/Kingfisher-Demo/Base.lproj/Main.storyboard +++ b/Demo/Demo/Kingfisher-Demo/Base.lproj/Main.storyboard @@ -1,9 +1,9 @@ - + - + @@ -67,14 +67,14 @@ - + - + @@ -108,7 +108,7 @@ - + @@ -127,12 +127,12 @@ - + - + @@ -156,7 +156,7 @@ - + @@ -180,7 +180,7 @@ - + @@ -204,7 +204,7 @@ - + @@ -228,7 +228,7 @@ - + @@ -252,7 +252,7 @@ - + @@ -276,7 +276,7 @@ - + @@ -300,7 +300,7 @@ - + @@ -324,7 +324,7 @@ - + @@ -348,7 +348,7 @@ - + @@ -372,7 +372,7 @@ - + @@ -396,7 +396,7 @@ - + @@ -420,7 +420,7 @@ - + @@ -444,7 +444,7 @@ - + @@ -468,7 +468,7 @@ - + @@ -563,7 +563,7 @@