diff --git a/Shared/View/History/HistoryRowView.swift b/Shared/View/History/HistoryRowView.swift index 0d4786c..d2966a4 100644 --- a/Shared/View/History/HistoryRowView.swift +++ b/Shared/View/History/HistoryRowView.swift @@ -35,14 +35,10 @@ struct HistoryRowView: View { @ViewBuilder private var memeRow: some View { HStack { - AsyncImage(url: meme.url) { - Image(Asset.Images.memeNotFound.name) - .resizable() - .aspectRatio(contentMode: .fill) - } - .aspectRatio(contentMode: .fill) - .frame(maxWidth: 60, maxHeight: 60) - .clipShape(RoundedRectangle(cornerRadius: .smallRadius)) + MemeImage(url: meme.url) + .aspectRatio(contentMode: .fill) + .frame(maxWidth: 60, maxHeight: 60) + .clipShape(RoundedRectangle(cornerRadius: .smallRadius)) VStack(alignment: .leading, spacing: .margin) { diff --git a/Shared/View/History/MemeDetails.swift b/Shared/View/History/MemeDetails.swift index cbddeec..71e04bc 100644 --- a/Shared/View/History/MemeDetails.swift +++ b/Shared/View/History/MemeDetails.swift @@ -42,43 +42,39 @@ struct MemeDetails: View { .edgesIgnoringSafeArea(.all) VStack(spacing: .margin) { - AsyncImage(url: meme.url) { - Image("meme-not-found") - .resizable() - .aspectRatio(contentMode: .fit) - } - .aspectRatio(contentMode: .fit) - .cornerRadius(.cornerRadius) - .shadow(radius: .smallRadius) - .contextMenu( - menuItems: { - #if os(iOS) || os(watchOS) || os(tvOS) - Button { - showShareSheet = true - } label: { - Label("Share", systemImage: "square.and.arrow.up") - } - - Button { - let pasteboard = UIPasteboard.general - pasteboard.url = meme.url - } label: { - Image(systemName: "doc.on.doc") - Text("Copy") - } - #elseif os(macOS) - ShareMenu(sharedItems: [meme.url], showText: true) - #endif - - Button { - openMemeInBrowser() - } label: { - Image(systemName: "safari") - Text("Open in Browser") + MemeImage(url: meme.url) + .scaledToFit() + .cornerRadius(.cornerRadius) + .shadow(radius: .smallRadius) + .contextMenu( + menuItems: { + #if os(iOS) || os(watchOS) || os(tvOS) + Button { + showShareSheet = true + } label: { + Label("Share", systemImage: "square.and.arrow.up") + } + + Button { + let pasteboard = UIPasteboard.general + pasteboard.url = meme.url + } label: { + Image(systemName: "doc.on.doc") + Text("Copy") + } + #elseif os(macOS) + ShareMenu(sharedItems: [meme.url], showText: true) + #endif + + Button { + openMemeInBrowser() + } label: { + Image(systemName: "safari") + Text("Open in Browser") + } } - } - ) - .contentShape(RoundedRectangle(cornerRadius: .smallRadius)) + ) + .contentShape(RoundedRectangle(cornerRadius: .smallRadius)) detailsView .background(Color.systemBackground) diff --git a/Shared/View/Home/MemeCardView.swift b/Shared/View/Home/MemeCardView.swift index 088fbf7..9dc4d16 100644 --- a/Shared/View/Home/MemeCardView.swift +++ b/Shared/View/Home/MemeCardView.swift @@ -28,51 +28,47 @@ struct MemeCardView: View { .frame(width: 0, height: 0) .hidden() - AsyncImage(url: meme.url) { - Image(Asset.Images.memeNotFound.name) - .resizable() - .aspectRatio(contentMode: .fit) - } - .aspectRatio(contentMode: .fit) - .cornerRadius(.cornerRadius) - .padding(.margin) - .frame( - maxWidth: geometrySize.width, - maxHeight: geometrySize.height/2 - ) - .foregroundColor(.secondarySystemBackground) - .animation(.interactiveSpring()) - .offset(x: self.translation.width, y: self.translation.height) - .rotationEffect( - .degrees(Double(self.translation.width / geometrySize.width) * 25), - anchor: .bottom - ) - .gesture( - DragGesture() - .onChanged { value in - self.translation = value.translation - self.swipingAction = value.translation.swipeDirection.asMemeAction - } - .onEnded { value in - /// remove overlay - self.swipingAction = nil + MemeImage(url: meme.url) + .aspectRatio(contentMode: .fit) + .cornerRadius(.cornerRadius) + .padding(.margin) + .frame( + maxWidth: geometrySize.width, + maxHeight: geometrySize.height/2 + ) + .foregroundColor(.secondarySystemBackground) + .animation(.interactiveSpring(), value: translation) + .offset(x: self.translation.width, y: self.translation.height) + .rotationEffect( + .degrees(Double(self.translation.width / geometrySize.width) * 25), + anchor: .bottom + ) + .gesture( + DragGesture() + .onChanged { value in + self.translation = value.translation + self.swipingAction = value.translation.swipeDirection.asMemeAction + } + .onEnded { value in + /// remove overlay + self.swipingAction = nil - /// complete swipe - switch value.translation.swipeDirection { - case .up: - self.swipe(.skip) - case .down: - self.translation = .zero - case .left: - self.swipe(.dislike) - case .right: - self.swipe(.like) + /// complete swipe + switch value.translation.swipeDirection { + case .up: + self.swipe(.skip) + case .down: + self.translation = .zero + case .left: + self.swipe(.dislike) + case .right: + self.swipe(.like) + } } - } - ) - .onTapGesture { - showMeme = true - } + ) + .onTapGesture { + showMeme = true + } } } diff --git a/Shared/View/Image/AsyncImage.swift b/Shared/View/Image/AsyncImage.swift deleted file mode 100644 index ffb0cde..0000000 --- a/Shared/View/Image/AsyncImage.swift +++ /dev/null @@ -1,91 +0,0 @@ -// -// AsyncImage.swift -// Tendr -// -// Created by Vince on 2021-02-19. -// - -import Combine -import SwiftUI -import Kingfisher - -public struct AsyncImage: View { - private let placeholder: Placeholder? - private let url: URL? - @State private var progress: Float = 0 - @State private var totalProgress: Float = 100 - @State private var isLoaded: Bool = false - - /// Return an `AsyncImage`. - /// - Parameters: - /// - url: url in which the image will be loaded from. - /// - placeholder: placeholder view that will display on failure to load image. - public init(url: URL?, @ViewBuilder placeholder: () -> Placeholder? = {nil}) { - self.url = url - self.placeholder = placeholder() - } - - public var body: some View { - KFImage(url, isLoaded: $isLoaded) - .placeholder {placeholder} - .resizable() - .onProgress { (recievedSize, totalSize) in - withAnimation { - progress = Float(recievedSize) - totalProgress = Float(totalSize) - } - } - .onFailure { _ in - withAnimation { - isLoaded = true - } - } - .overlay( - progressView, - alignment: .bottom - ) - } - - @ViewBuilder private var progressView: some View { - if !isLoaded { - ZStack(alignment: .bottom) { - Color.black.opacity(0.6) - .frame(maxWidth: .infinity, maxHeight: .infinity) - .blur(radius: 1.5) - - ProgressView(value: progress, total: totalProgress) - } - .transition(.opacity) - } - } -} - -#if DEBUG -struct AsyncImage_Previews: PreviewProvider { - private static var placeholder: some View { - Image(systemName: "photo") - .resizable() - .aspectRatio(contentMode: .fit) - .foregroundColor(.gray) - .padding() - } - - static var previews: some View { - Group { - // Test a very large image. - AsyncImage(url: URL(string: "https://eoimages.gsfc.nasa.gov/images/imagerecords/73000/73580/world.topo.bathy.200401.3x21600x21600.A2.jpg")!) { - placeholder - } - .previewDisplayName("Shows Downloaded Image") - .previewLayout(.sizeThatFits) - - AsyncImage( - url: URL(string: "esr://brokenphoto")!) { - placeholder - } - .previewDisplayName("Shows Placeholder") - .previewLayout(.sizeThatFits) - } - } -} -#endif diff --git a/Shared/View/Image/MemeImage.swift b/Shared/View/Image/MemeImage.swift new file mode 100644 index 0000000..5719743 --- /dev/null +++ b/Shared/View/Image/MemeImage.swift @@ -0,0 +1,73 @@ +// +// MemeImage.swift +// MemeImage +// +// Created by Brent Mifsud on 2021-09-14. +// + +import SwiftUI +import os + +struct MemeImage: View { + private class MemeCache { + private lazy var cache = [URL: Image]() + + func set(image: Image, for url: URL) { + cache[url] = image + } + + func getImage(for url: URL) -> Image? { + cache[url] + } + + func clearCache() { + cache = [:] + } + } + + private static let cache = MemeCache() + + var url: URL? + + var body: some View { + if let url = url, + let image = Self.cache.getImage(for: url) { + image.resizable() + } else { + AsyncImage( + url: url, + scale: 1.0, + transaction: Transaction(animation: .easeOut(duration: 0.2)) + ) { phase in + switch phase { + case .empty: + Color.secondary + .overlay(ProgressView().progressViewStyle(.circular)) + case let .success(image): + cacheAndReturnImage(image: image) + .resizable() + .transition(.opacity) + case .failure: + Image("meme-not-found") + .resizable() + .transition(.opacity) + @unknown default: + Image("meme-not-found") + .resizable() + } + } + } + } + + private func cacheAndReturnImage(image: Image) -> Image { + guard let url = url else { return image } + Self.cache.set(image: image, for: url) + return image + } +} + +struct MemeImage_Previews: PreviewProvider { + static var previews: some View { + MemeImage() + } +} diff --git a/Tendr.xcodeproj/project.pbxproj b/Tendr.xcodeproj/project.pbxproj index a862401..fab560c 100644 --- a/Tendr.xcodeproj/project.pbxproj +++ b/Tendr.xcodeproj/project.pbxproj @@ -3,12 +3,11 @@ archiveVersion = 1; classes = { }; - objectVersion = 52; + objectVersion = 50; objects = { /* Begin PBXBuildFile section */ 611A41C025E21AE00053C010 /* HistoryProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 611A41BF25E21AE00053C010 /* HistoryProvider.swift */; }; - 613E7EBB25E0711700F20A53 /* AsyncImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 616A1C2825E0452A0062BB89 /* AsyncImage.swift */; }; 613E7EC425E0781700F20A53 /* Image+Initializer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 613E7EC325E0781700F20A53 /* Image+Initializer.swift */; }; 613E7EC525E0781700F20A53 /* Image+Initializer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 613E7EC325E0781700F20A53 /* Image+Initializer.swift */; }; 613E7ECF25E096C200F20A53 /* HomeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 613E7ECE25E096C200F20A53 /* HomeView.swift */; }; @@ -24,7 +23,6 @@ 613E7EE925E0B03F00F20A53 /* MemeAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 613E7EE825E0B03F00F20A53 /* MemeAction.swift */; }; 613E7EEA25E0B03F00F20A53 /* MemeAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 613E7EE825E0B03F00F20A53 /* MemeAction.swift */; }; 613E7EEE25E0BA4F00F20A53 /* Color+iOS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 613E7EED25E0BA4F00F20A53 /* Color+iOS.swift */; }; - 616A1C2925E0452A0062BB89 /* AsyncImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 616A1C2825E0452A0062BB89 /* AsyncImage.swift */; }; 8421F10125E022ED00B12D0B /* TendrApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8421F0EE25E022EA00B12D0B /* TendrApp.swift */; }; 8421F10325E022ED00B12D0B /* RootView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8421F0EF25E022EA00B12D0B /* RootView.swift */; }; 8421F10525E022ED00B12D0B /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 8421F0F025E022ED00B12D0B /* Images.xcassets */; }; @@ -69,8 +67,6 @@ 84944A2B25ED9FFE000B8BCB /* MemeHistoryList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84944A2925ED9FFE000B8BCB /* MemeHistoryList.swift */; }; 84944A3125EDA296000B8BCB /* AlertContent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84944A3025EDA296000B8BCB /* AlertContent.swift */; }; 84944A3225EDA296000B8BCB /* AlertContent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84944A3025EDA296000B8BCB /* AlertContent.swift */; }; - 84944A6225EDE433000B8BCB /* Kingfisher in Frameworks */ = {isa = PBXBuildFile; productRef = 84944A6125EDE433000B8BCB /* Kingfisher */; }; - 84944A6725EDE443000B8BCB /* Kingfisher in Frameworks */ = {isa = PBXBuildFile; productRef = 84944A6625EDE443000B8BCB /* Kingfisher */; }; 84944A7225EDF001000B8BCB /* ShareToolbarItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84944A7125EDF001000B8BCB /* ShareToolbarItem.swift */; }; 84944A8225EE0B99000B8BCB /* AuthManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8421F11525E02BF400B12D0B /* AuthManager.swift */; }; 84944A8625EE0BB1000B8BCB /* AuthManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8421F11525E02BF400B12D0B /* AuthManager.swift */; }; @@ -80,6 +76,8 @@ 84986DB925E16C3A00A882A5 /* CreditsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84986DB725E16C3A00A882A5 /* CreditsView.swift */; }; 84E0699226F02BB100BBCACC /* Colors.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 84E0699126F02BB100BBCACC /* Colors.xcassets */; }; 84E0699326F02BB100BBCACC /* Colors.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 84E0699126F02BB100BBCACC /* Colors.xcassets */; }; + 84E0699626F06B5D00BBCACC /* MemeImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84E0699526F06B5D00BBCACC /* MemeImage.swift */; }; + 84E0699726F06B5D00BBCACC /* MemeImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84E0699526F06B5D00BBCACC /* MemeImage.swift */; }; 84EC262325E0D03D00B045A0 /* MemeResponseTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84EC262225E0D03D00B045A0 /* MemeResponseTest.swift */; }; 84EC262C25E0D0AC00B045A0 /* MemeResponseArray.json in Resources */ = {isa = PBXBuildFile; fileRef = 84EC262B25E0D0AB00B045A0 /* MemeResponseArray.json */; }; 84EC263425E0D0CD00B045A0 /* JsonLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84EC263325E0D0CD00B045A0 /* JsonLoader.swift */; }; @@ -125,7 +123,6 @@ 613E7EE825E0B03F00F20A53 /* MemeAction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MemeAction.swift; sourceTree = ""; }; 613E7EED25E0BA4F00F20A53 /* Color+iOS.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Color+iOS.swift"; sourceTree = ""; }; 616A1C1125E031630062BB89 /* SettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsView.swift; sourceTree = ""; }; - 616A1C2825E0452A0062BB89 /* AsyncImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AsyncImage.swift; sourceTree = ""; }; 8421F0EE25E022EA00B12D0B /* TendrApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TendrApp.swift; sourceTree = ""; }; 8421F0EF25E022EA00B12D0B /* RootView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RootView.swift; sourceTree = ""; }; 8421F0F025E022ED00B12D0B /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; @@ -165,6 +162,7 @@ 84944A7125EDF001000B8BCB /* ShareToolbarItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareToolbarItem.swift; sourceTree = ""; }; 84986DB725E16C3A00A882A5 /* CreditsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreditsView.swift; sourceTree = ""; }; 84E0699126F02BB100BBCACC /* Colors.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Colors.xcassets; sourceTree = ""; }; + 84E0699526F06B5D00BBCACC /* MemeImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MemeImage.swift; sourceTree = ""; }; 84EC25E725E0CA7A00B045A0 /* Tendr.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Tendr.entitlements; sourceTree = ""; }; 84EC262225E0D03D00B045A0 /* MemeResponseTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MemeResponseTest.swift; sourceTree = ""; }; 84EC262B25E0D0AB00B045A0 /* MemeResponseArray.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = MemeResponseArray.json; sourceTree = ""; }; @@ -186,7 +184,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 84944A6225EDE433000B8BCB /* Kingfisher in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -194,7 +191,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 84944A6725EDE443000B8BCB /* Kingfisher in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -232,14 +228,6 @@ path = Home; sourceTree = ""; }; - 616A1C2725E0451B0062BB89 /* Image */ = { - isa = PBXGroup; - children = ( - 616A1C2825E0452A0062BB89 /* AsyncImage.swift */, - ); - path = Image; - sourceTree = ""; - }; 8421F0E825E022EA00B12D0B = { isa = PBXGroup; children = ( @@ -333,9 +321,9 @@ 8421F14425E03AB200B12D0B /* View */ = { isa = PBXGroup; children = ( + 84E0699426F06B3F00BBCACC /* Image */, 84944A8E25EE0C94000B8BCB /* Settings */, 613E7ED325E09A4B00F20A53 /* Home */, - 616A1C2725E0451B0062BB89 /* Image */, 846574E525E0432000BA7A3D /* LoginPage.swift */, 8421F0EF25E022EA00B12D0B /* RootView.swift */, 846574E925E0440A00BA7A3D /* Button Style */, @@ -473,6 +461,14 @@ path = Settings; sourceTree = ""; }; + 84E0699426F06B3F00BBCACC /* Image */ = { + isa = PBXGroup; + children = ( + 84E0699526F06B5D00BBCACC /* MemeImage.swift */, + ); + path = Image; + sourceTree = ""; + }; 84EC262125E0D02200B045A0 /* Model */ = { isa = PBXGroup; children = ( @@ -546,7 +542,6 @@ ); name = "Tendr (iOS)"; packageProductDependencies = ( - 84944A6125EDE433000B8BCB /* Kingfisher */, ); productName = "Tendr (iOS)"; productReference = 8421F0F525E022ED00B12D0B /* Tendr.app */; @@ -568,7 +563,6 @@ ); name = "Tendr (macOS)"; packageProductDependencies = ( - 84944A6625EDE443000B8BCB /* Kingfisher */, ); productName = "Tendr (macOS)"; productReference = 8421F0FD25E022ED00B12D0B /* Tendr.app */; @@ -623,7 +617,6 @@ ); mainGroup = 8421F0E825E022EA00B12D0B; packageReferences = ( - 84944A6025EDE433000B8BCB /* XCRemoteSwiftPackageReference "kingfisher" */, ); productRefGroup = 8421F0F625E022ED00B12D0B /* Products */; projectDirPath = ""; @@ -766,6 +759,7 @@ 845C915C25E238A3009EF7AB /* Constants.swift in Sources */, 8421F10325E022ED00B12D0B /* RootView.swift in Sources */, 84986DB825E16C3A00A882A5 /* CreditsView.swift in Sources */, + 84E0699626F06B5D00BBCACC /* MemeImage.swift in Sources */, 846574EB25E0442800BA7A3D /* LargeButtonStyle.swift in Sources */, 847961FD26F038F900521185 /* Assets.swift in Sources */, 846574E625E0432000BA7A3D /* LoginPage.swift in Sources */, @@ -777,7 +771,6 @@ 845C916425E23BD9009EF7AB /* NetworkClient.swift in Sources */, 613E7EEE25E0BA4F00F20A53 /* Color+iOS.swift in Sources */, 845C914225E21540009EF7AB /* AuthRequest.swift in Sources */, - 616A1C2925E0452A0062BB89 /* AsyncImage.swift in Sources */, 613E7ED525E09A5D00F20A53 /* MemeProvider.swift in Sources */, 845C909B25E1A4E8009EF7AB /* AppSection.swift in Sources */, 613E7EDF25E09EFA00F20A53 /* MemeButtonsView.swift in Sources */, @@ -803,7 +796,6 @@ 613E7EC525E0781700F20A53 /* Image+Initializer.swift in Sources */, 845C910225E1E9A5009EF7AB /* View+Hidden.swift in Sources */, 613E7ED025E096C200F20A53 /* HomeView.swift in Sources */, - 613E7EBB25E0711700F20A53 /* AsyncImage.swift in Sources */, 613E7EEA25E0B03F00F20A53 /* MemeAction.swift in Sources */, 845C919F25E263DD009EF7AB /* HistoryView.swift in Sources */, 845C920625E310C6009EF7AB /* MemeDetails.swift in Sources */, @@ -814,6 +806,7 @@ 845C91A325E265BA009EF7AB /* HistoryProvider.swift in Sources */, 613E7ED625E09A5D00F20A53 /* MemeProvider.swift in Sources */, 84EF270E25E09B6B00061513 /* ApiRequest.swift in Sources */, + 84E0699726F06B5D00BBCACC /* MemeImage.swift in Sources */, 847961FE26F038F900521185 /* Assets.swift in Sources */, 845C916525E23BD9009EF7AB /* NetworkClient.swift in Sources */, 845C912B25E1EB0A009EF7AB /* AppStorageConstants.swift in Sources */, @@ -1004,7 +997,7 @@ DEVELOPMENT_TEAM = M5MTT5YDN9; ENABLE_PREVIEWS = YES; INFOPLIST_FILE = iOS/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 14.0; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -1031,7 +1024,7 @@ DEVELOPMENT_TEAM = M5MTT5YDN9; ENABLE_PREVIEWS = YES; INFOPLIST_FILE = iOS/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 14.0; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -1065,7 +1058,7 @@ "$(inherited)", "@executable_path/../Frameworks", ); - MACOSX_DEPLOYMENT_TARGET = 11.0; + MACOSX_DEPLOYMENT_TARGET = 12.0; MARKETING_VERSION = 1.0.0; PRODUCT_BUNDLE_IDENTIFIER = com.codingcouch.tendr; PRODUCT_NAME = Tendr; @@ -1093,7 +1086,7 @@ "$(inherited)", "@executable_path/../Frameworks", ); - MACOSX_DEPLOYMENT_TARGET = 11.0; + MACOSX_DEPLOYMENT_TARGET = 12.0; MARKETING_VERSION = 1.0.0; PRODUCT_BUNDLE_IDENTIFIER = com.codingcouch.tendr; PRODUCT_NAME = Tendr; @@ -1186,30 +1179,6 @@ defaultConfigurationName = Release; }; /* End XCConfigurationList section */ - -/* Begin XCRemoteSwiftPackageReference section */ - 84944A6025EDE433000B8BCB /* XCRemoteSwiftPackageReference "kingfisher" */ = { - isa = XCRemoteSwiftPackageReference; - repositoryURL = "https://github.com/onevcat/kingfisher.git"; - requirement = { - kind = upToNextMajorVersion; - minimumVersion = 6.1.1; - }; - }; -/* End XCRemoteSwiftPackageReference section */ - -/* Begin XCSwiftPackageProductDependency section */ - 84944A6125EDE433000B8BCB /* Kingfisher */ = { - isa = XCSwiftPackageProductDependency; - package = 84944A6025EDE433000B8BCB /* XCRemoteSwiftPackageReference "kingfisher" */; - productName = Kingfisher; - }; - 84944A6625EDE443000B8BCB /* Kingfisher */ = { - isa = XCSwiftPackageProductDependency; - package = 84944A6025EDE433000B8BCB /* XCRemoteSwiftPackageReference "kingfisher" */; - productName = Kingfisher; - }; -/* End XCSwiftPackageProductDependency section */ }; rootObject = 8421F0E925E022EA00B12D0B /* Project object */; }