Mercurial > public > simoleon
changeset 158:82bd84c5973c
Implemented Favorite Button
author | Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com> |
---|---|
date | Sat, 28 Aug 2021 19:17:55 +0100 |
parents | 8c3bbd640103 |
children | 35628bac01f5 |
files | Simoleon.xcodeproj/project.pbxproj Simoleon.xcodeproj/xcshareddata/xcschemes/Simoleon.xcscheme Simoleon/ContentView.swift Simoleon/Models/DefaultCurrency+CoreDataClass.swift Simoleon/Models/DefaultCurrency+CoreDataProperties.swift Simoleon/Models/Favorite+CoreDataClass.swift Simoleon/Models/Favorite+CoreDataProperties.swift Simoleon/Models/FavoritePair+CoreDataClass.swift Simoleon/Models/FavoritePair+CoreDataProperties.swift Simoleon/Simoleon.xcdatamodeld/Simoleon.xcdatamodel/contents Simoleon/Tests/ButtonAnimation.swift Simoleon/UI/FavoriteButton.swift Simoleon/UI/LockedCurrencyPicker.swift |
diffstat | 13 files changed, 167 insertions(+), 199 deletions(-) [+] |
line wrap: on
line diff
--- a/Simoleon.xcodeproj/project.pbxproj Sat Aug 28 11:15:41 2021 +0100 +++ b/Simoleon.xcodeproj/project.pbxproj Sat Aug 28 19:17:55 2021 +0100 @@ -22,15 +22,14 @@ 957DCF3326D7ADEA00BCAB1E /* CurrencyPairModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 957DCF3226D7ADEA00BCAB1E /* CurrencyPairModel.swift */; }; 95851CE326D4DAAE004ADA79 /* CurrencyButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95851CE226D4DAAE004ADA79 /* CurrencyButton.swift */; }; 95851CE526D4DB4C004ADA79 /* Flag.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95851CE426D4DB4C004ADA79 /* Flag.swift */; }; - 95851CE826D4E552004ADA79 /* DefaultCurrency+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95851CE626D4E552004ADA79 /* DefaultCurrency+CoreDataClass.swift */; }; - 95851CE926D4E552004ADA79 /* DefaultCurrency+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95851CE726D4E552004ADA79 /* DefaultCurrency+CoreDataProperties.swift */; }; - 95851CF026D4E89C004ADA79 /* Favorite+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95851CEE26D4E89C004ADA79 /* Favorite+CoreDataClass.swift */; }; - 95851CF126D4E89C004ADA79 /* Favorite+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95851CEF26D4E89C004ADA79 /* Favorite+CoreDataProperties.swift */; }; 9585BB1426A6B7F400E3193E /* NetworkHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9585BB1326A6B7F400E3193E /* NetworkHelper.swift */; }; 9585BB1A26A6E8FD00E3193E /* HapticsHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9585BB1926A6E8FD00E3193E /* HapticsHelper.swift */; }; 95909CB326B07BFC00D051AB /* SearchBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95909CB226B07BFC00D051AB /* SearchBar.swift */; }; 959F6DEB26BBD53500101E53 /* SimoleonScreenshots.swift in Sources */ = {isa = PBXBuildFile; fileRef = 959F6DEA26BBD53500101E53 /* SimoleonScreenshots.swift */; }; 95AA42ED26D78A4A0085570D /* FileHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95AA42EC26D78A4A0085570D /* FileHelper.swift */; }; + 95AC820726DAA3ED00CD5C3F /* FavoritePair+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95AC820526DAA3ED00CD5C3F /* FavoritePair+CoreDataClass.swift */; }; + 95AC820826DAA3ED00CD5C3F /* FavoritePair+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95AC820626DAA3ED00CD5C3F /* FavoritePair+CoreDataProperties.swift */; }; + 95AC820A26DAAC6B00CD5C3F /* ButtonAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95AC820926DAAC6B00CD5C3F /* ButtonAnimation.swift */; }; 95AEBC9526A03ECB00613729 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95AEBC9426A03ECB00613729 /* ContentView.swift */; }; 95AEBC9D26A04D4600613729 /* CurrencyRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95AEBC9C26A04D4600613729 /* CurrencyRow.swift */; }; 95AEBCA326A0900E00613729 /* CurrencyQuoteModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95AEBCA226A0900E00613729 /* CurrencyQuoteModel.swift */; }; @@ -127,10 +126,6 @@ 957DCF3226D7ADEA00BCAB1E /* CurrencyPairModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CurrencyPairModel.swift; sourceTree = "<group>"; }; 95851CE226D4DAAE004ADA79 /* CurrencyButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CurrencyButton.swift; sourceTree = "<group>"; }; 95851CE426D4DB4C004ADA79 /* Flag.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Flag.swift; sourceTree = "<group>"; }; - 95851CE626D4E552004ADA79 /* DefaultCurrency+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DefaultCurrency+CoreDataClass.swift"; sourceTree = "<group>"; }; - 95851CE726D4E552004ADA79 /* DefaultCurrency+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DefaultCurrency+CoreDataProperties.swift"; sourceTree = "<group>"; }; - 95851CEE26D4E89C004ADA79 /* Favorite+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Favorite+CoreDataClass.swift"; sourceTree = "<group>"; }; - 95851CEF26D4E89C004ADA79 /* Favorite+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Favorite+CoreDataProperties.swift"; sourceTree = "<group>"; }; 9585BB0F26A6B58500E3193E /* Config.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Config.xcconfig; sourceTree = "<group>"; }; 9585BB1326A6B7F400E3193E /* NetworkHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkHelper.swift; sourceTree = "<group>"; }; 9585BB1926A6E8FD00E3193E /* HapticsHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HapticsHelper.swift; sourceTree = "<group>"; }; @@ -154,6 +149,9 @@ 959F6DEC26BBD53500101E53 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; 95A70BE926B0550000CC0273 /* CloudKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CloudKit.framework; path = Platforms/WatchOS.platform/Developer/SDKs/WatchOS7.4.sdk/System/Library/Frameworks/CloudKit.framework; sourceTree = DEVELOPER_DIR; }; 95AA42EC26D78A4A0085570D /* FileHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileHelper.swift; sourceTree = "<group>"; }; + 95AC820526DAA3ED00CD5C3F /* FavoritePair+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "FavoritePair+CoreDataClass.swift"; sourceTree = "<group>"; }; + 95AC820626DAA3ED00CD5C3F /* FavoritePair+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "FavoritePair+CoreDataProperties.swift"; sourceTree = "<group>"; }; + 95AC820926DAAC6B00CD5C3F /* ButtonAnimation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonAnimation.swift; sourceTree = "<group>"; }; 95AEBC9426A03ECB00613729 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; }; 95AEBC9C26A04D4600613729 /* CurrencyRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CurrencyRow.swift; sourceTree = "<group>"; }; 95AEBCA226A0900E00613729 /* CurrencyQuoteModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CurrencyQuoteModel.swift; sourceTree = "<group>"; }; @@ -255,10 +253,8 @@ 95559331269B094A000FD726 /* Models */ = { isa = PBXGroup; children = ( - 95851CEE26D4E89C004ADA79 /* Favorite+CoreDataClass.swift */, - 95851CEF26D4E89C004ADA79 /* Favorite+CoreDataProperties.swift */, - 95851CE626D4E552004ADA79 /* DefaultCurrency+CoreDataClass.swift */, - 95851CE726D4E552004ADA79 /* DefaultCurrency+CoreDataProperties.swift */, + 95AC820526DAA3ED00CD5C3F /* FavoritePair+CoreDataClass.swift */, + 95AC820626DAA3ED00CD5C3F /* FavoritePair+CoreDataProperties.swift */, 95AEBCA226A0900E00613729 /* CurrencyQuoteModel.swift */, 953B8B1626D3A970003CF530 /* CurrencyDetailsModel.swift */, 957DCF3226D7ADEA00BCAB1E /* CurrencyPairModel.swift */, @@ -420,6 +416,7 @@ isa = PBXGroup; children = ( 95DA4B5826D7E2DE00566C5E /* ChildListResets.swift */, + 95AC820926DAAC6B00CD5C3F /* ButtonAnimation.swift */, ); path = Tests; sourceTree = "<group>"; @@ -687,13 +684,12 @@ buildActionMask = 2147483647; files = ( 95C5179926A5EC9F00BC2B24 /* FavoriteButton.swift in Sources */, - 95851CF126D4E89C004ADA79 /* Favorite+CoreDataProperties.swift in Sources */, + 95AC820726DAA3ED00CD5C3F /* FavoritePair+CoreDataClass.swift in Sources */, 9522CD9D26CED2E100DD9D03 /* ErrorHandling.swift in Sources */, 95AA42ED26D78A4A0085570D /* FileHelper.swift in Sources */, 95851CE326D4DAAE004ADA79 /* CurrencyButton.swift in Sources */, 95C5B2312697752700941585 /* Persistence.swift in Sources */, 95DA4B5926D7E2DE00566C5E /* ChildListResets.swift in Sources */, - 95851CF026D4E89C004ADA79 /* Favorite+CoreDataClass.swift in Sources */, 95AEBC9526A03ECB00613729 /* ContentView.swift in Sources */, 9522BEAB26B5AACB0076B098 /* ListModifier.swift in Sources */, 95909CB326B07BFC00D051AB /* SearchBar.swift in Sources */, @@ -701,13 +697,14 @@ 9522BEA926B5A4D20076B098 /* AppDelegate.swift in Sources */, 95851CE526D4DB4C004ADA79 /* Flag.swift in Sources */, 95D8C8CD26A9784500BCC188 /* SubscribeButton.swift in Sources */, - 95851CE926D4E552004ADA79 /* DefaultCurrency+CoreDataProperties.swift in Sources */, 9585BB1A26A6E8FD00E3193E /* HapticsHelper.swift in Sources */, 95D8C8CF26A98A7900BCC188 /* RestoreButton.swift in Sources */, 95C5179F26A5F34200BC2B24 /* FavoritesView.swift in Sources */, 95C5B2282697752600941585 /* SimoleonApp.swift in Sources */, 95B54F4A26A4A450001DC0D8 /* ConversionBox.swift in Sources */, 95D8C8C726A95D2900BCC188 /* SubscriptionPaywall.swift in Sources */, + 95AC820A26DAAC6B00CD5C3F /* ButtonAnimation.swift in Sources */, + 95AC820826DAA3ED00CD5C3F /* FavoritePair+CoreDataProperties.swift in Sources */, 95D8C8D126A9BC6200BCC188 /* LockedCurrencyPicker.swift in Sources */, 95C517A126A5F6C000BC2B24 /* ResignKeyboard.swift in Sources */, 95CE6A3626D50B7700D9DCBD /* CurrencyList.swift in Sources */, @@ -722,7 +719,6 @@ 95C5179126A5DC8E00BC2B24 /* ConditionalWrapper.swift in Sources */, 95B54F5126A4ACAC001DC0D8 /* Sidebar.swift in Sources */, 95561E3F26AF25EF00CCB543 /* SubscriptionFeature.swift in Sources */, - 95851CE826D4E552004ADA79 /* DefaultCurrency+CoreDataClass.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; };
--- a/Simoleon.xcodeproj/xcshareddata/xcschemes/Simoleon.xcscheme Sat Aug 28 11:15:41 2021 +0100 +++ b/Simoleon.xcodeproj/xcshareddata/xcschemes/Simoleon.xcscheme Sat Aug 28 19:17:55 2021 +0100 @@ -104,8 +104,7 @@ ignoresPersistentStateOnLaunch = "NO" debugDocumentVersioning = "YES" debugServiceExtension = "internal" - allowLocationSimulation = "YES" - showNonLocalizedStrings = "YES"> + allowLocationSimulation = "YES"> <BuildableProductRunnable runnableDebuggingMode = "0"> <BuildableReference
--- a/Simoleon/ContentView.swift Sat Aug 28 11:15:41 2021 +0100 +++ b/Simoleon/ContentView.swift Sat Aug 28 19:17:55 2021 +0100 @@ -8,8 +8,6 @@ import SwiftUI struct ContentView: View { - @Environment(\.managedObjectContext) private var viewContext - @FetchRequest(sortDescriptors: []) private var defaultCurrency: FetchedResults<DefaultCurrency> @State private var tab: Tab = .convert private enum Tab {
--- a/Simoleon/Models/DefaultCurrency+CoreDataClass.swift Sat Aug 28 11:15:41 2021 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,15 +0,0 @@ -// -// DefaultCurrency+CoreDataClass.swift -// Simoleon -// -// Created by Dennis Concepción Martín on 24/8/21. -// -// - -import Foundation -import CoreData - -@objc(DefaultCurrency) -public class DefaultCurrency: NSManagedObject { - -}
--- a/Simoleon/Models/DefaultCurrency+CoreDataProperties.swift Sat Aug 28 11:15:41 2021 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,26 +0,0 @@ -// -// DefaultCurrency+CoreDataProperties.swift -// Simoleon -// -// Created by Dennis Concepción Martín on 24/8/21. -// -// - -import Foundation -import CoreData - - -extension DefaultCurrency { - - @nonobjc public class func fetchRequest() -> NSFetchRequest<DefaultCurrency> { - return NSFetchRequest<DefaultCurrency>(entityName: "DefaultCurrency") - } - - @NSManaged public var firstSymbol: String - @NSManaged public var secondSymbol: String - -} - -extension DefaultCurrency : Identifiable { - -}
--- a/Simoleon/Models/Favorite+CoreDataClass.swift Sat Aug 28 11:15:41 2021 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,15 +0,0 @@ -// -// Favorite+CoreDataClass.swift -// Simoleon -// -// Created by Dennis Concepción Martín on 24/8/21. -// -// - -import Foundation -import CoreData - -@objc(Favorite) -public class Favorite: NSManagedObject { - -}
--- a/Simoleon/Models/Favorite+CoreDataProperties.swift Sat Aug 28 11:15:41 2021 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,25 +0,0 @@ -// -// Favorite+CoreDataProperties.swift -// Simoleon -// -// Created by Dennis Concepción Martín on 24/8/21. -// -// - -import Foundation -import CoreData - - -extension Favorite { - - @nonobjc public class func fetchRequest() -> NSFetchRequest<Favorite> { - return NSFetchRequest<Favorite>(entityName: "Favorite") - } - - @NSManaged public var currencyPair: String - -} - -extension Favorite : Identifiable { - -}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Simoleon/Models/FavoritePair+CoreDataClass.swift Sat Aug 28 19:17:55 2021 +0100 @@ -0,0 +1,15 @@ +// +// FavoritePair+CoreDataClass.swift +// Simoleon +// +// Created by Dennis Concepción Martín on 28/8/21. +// +// + +import Foundation +import CoreData + +@objc(FavoritePair) +public class FavoritePair: NSManagedObject { + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Simoleon/Models/FavoritePair+CoreDataProperties.swift Sat Aug 28 19:17:55 2021 +0100 @@ -0,0 +1,26 @@ +// +// FavoritePair+CoreDataProperties.swift +// Simoleon +// +// Created by Dennis Concepción Martín on 28/8/21. +// +// + +import Foundation +import CoreData + + +extension FavoritePair { + + @nonobjc public class func fetchRequest() -> NSFetchRequest<FavoritePair> { + return NSFetchRequest<FavoritePair>(entityName: "FavoritePair") + } + + @NSManaged public var baseSymbol: String? + @NSManaged public var quoteSymbol: String? + +} + +extension FavoritePair : Identifiable { + +}
--- a/Simoleon/Simoleon.xcdatamodeld/Simoleon.xcdatamodel/contents Sat Aug 28 11:15:41 2021 +0100 +++ b/Simoleon/Simoleon.xcdatamodeld/Simoleon.xcdatamodel/contents Sat Aug 28 19:17:55 2021 +0100 @@ -1,14 +1,10 @@ <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="18154" systemVersion="20G95" minimumToolsVersion="Automatic" sourceLanguage="Swift" usedWithCloudKit="YES" userDefinedModelVersionIdentifier=""> - <entity name="DefaultCurrency" representedClassName="DefaultCurrency" syncable="YES"> - <attribute name="firstSymbol" optional="YES" attributeType="String"/> - <attribute name="secondSymbol" optional="YES" attributeType="String"/> - </entity> - <entity name="Favorite" representedClassName="Favorite" syncable="YES"> - <attribute name="currencyPair" optional="YES" attributeType="String"/> + <entity name="FavoritePair" representedClassName="FavoritePair" syncable="YES"> + <attribute name="baseSymbol" optional="YES" attributeType="String"/> + <attribute name="quoteSymbol" optional="YES" attributeType="String"/> </entity> <elements> - <element name="DefaultCurrency" positionX="0" positionY="0" width="128" height="59"/> - <element name="Favorite" positionX="0" positionY="0" width="128" height="44"/> + <element name="FavoritePair" positionX="-63" positionY="-18" width="128" height="59"/> </elements> </model> \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Simoleon/Tests/ButtonAnimation.swift Sat Aug 28 19:17:55 2021 +0100 @@ -0,0 +1,31 @@ +// +// ButtonAnimation.swift +// Simoleon +// +// Created by Dennis Concepción Martín on 28/8/21. +// + +import SwiftUI + +struct ButtonAnimation: View { + @State private var scale: CGFloat = 1 + + var body: some View { + Button("Press here", action: animate) + .scaleEffect(scale) + .animation(.easeIn, value: scale) + } + + private func animate() { + scale += 0.2 + DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) { + scale -= 0.2 + } + } +} + +struct ButtonAnimation_Previews: PreviewProvider { + static var previews: some View { + ButtonAnimation() + } +}
--- a/Simoleon/UI/FavoriteButton.swift Sat Aug 28 11:15:41 2021 +0100 +++ b/Simoleon/UI/FavoriteButton.swift Sat Aug 28 19:17:55 2021 +0100 @@ -9,94 +9,82 @@ struct FavoriteButton: View { @State var currencyPair: CurrencyPairModel + @State private var scale: CGFloat = 1 @Environment(\.managedObjectContext) private var viewContext - @FetchRequest(sortDescriptors: []) private var favorites: FetchedResults<Favorite> - @State private var starSymbol = "star" + @FetchRequest(sortDescriptors: []) private var favoritePairs: FetchedResults<FavoritePair> var body: some View { - Button(action: favoriteAction) { + Button(action: { + animate() + if isFavorite() { + remove() + } else { + add() + } + }) { RoundedRectangle(cornerRadius: 15) .foregroundColor(Color(.secondarySystemBackground)) .frame(width: 60, height: 60) .overlay( - Image(systemName: generateStar()) - .font(.system(size: 28)) - .foregroundColor(Color(.systemYellow)) + VStack { + if isFavorite() { + Image(systemName: "star.fill") + } else { + Image(systemName: "star") + } + } + .font(.system(size: 28)) + .foregroundColor(Color(.systemYellow)) ) } - .accessibilityIdentifier("AddToFavorites") + .scaleEffect(scale) + .animation(.linear(duration: 0.2), value: scale) } - /* - If currency pair is favorite: - * Button action is to remove from favorites - else: - * Button action is to add to favorites - */ - private func favoriteAction() { - let favoriteCurrencyPairs = favorites.map { $0.currencyPair } - let currencyPair = "(\(currencyPair.baseSymbol)/\(currencyPair.quoteSymbol)" - if favoriteCurrencyPairs.contains(currencyPair) { - removeFromFavorites() - } else { - addToFavorites() - } + func add() { + let favoritePair = FavoritePair(context: viewContext) + favoritePair.baseSymbol = currencyPair.baseSymbol + favoritePair.quoteSymbol = currencyPair.quoteSymbol - let haptics = Haptics() - haptics.simpleSuccess() - } - - /* - if currency pair is favorite: - * Return "star.fill" symbol - else: - * Return "star" - */ - private func generateStar() -> String { - let favoriteCurrencyPairs = favorites.map { $0.currencyPair } - let currencyPair = "(\(currencyPair.baseSymbol)/\(currencyPair.quoteSymbol)" - if favoriteCurrencyPairs.contains(currencyPair) { - return "star.fill" - } else { - return "star" + do { + try viewContext.save() + } catch { + let nsError = error as NSError + fatalError("Unresolved error \(nsError), \(nsError.userInfo)") } } - /* - * Get first favorite core data object that matches the specified currency pair - * Delete it - */ - private func removeFromFavorites() { - let currencyPair = "(\(currencyPair.baseSymbol)/\(currencyPair.quoteSymbol)" - withAnimation { - let favoriteObject = favorites.first(where: { $0.currencyPair == currencyPair }) - viewContext.delete(favoriteObject ?? Favorite()) - - do { - try viewContext.save() - } catch { - let nsError = error as NSError - fatalError("Unresolved error \(nsError), \(nsError.userInfo)") - } + func remove() { + let favoritePair = favoritePairs.first( + where: { + $0.baseSymbol == currencyPair.baseSymbol && $0.quoteSymbol == currencyPair.quoteSymbol + }) + + viewContext.delete(favoritePair!) + + do { + try viewContext.save() + } catch { + let nsError = error as NSError + fatalError("Unresolved error \(nsError), \(nsError.userInfo)") } } - /* - * Create a favorite core data object - * Save it - */ - private func addToFavorites() { - let currencyPair = "(\(currencyPair.baseSymbol)/\(currencyPair.quoteSymbol)" - withAnimation { - let favorite = Favorite(context: viewContext) - favorite.currencyPair = currencyPair - - do { - try viewContext.save() - } catch { - let nsError = error as NSError - fatalError("Unresolved error \(nsError), \(nsError.userInfo)") - } + func isFavorite() -> Bool { + let favoritePair = favoritePairs.first( + where: { + $0.baseSymbol == currencyPair.baseSymbol && $0.quoteSymbol == currencyPair.quoteSymbol + }) + + guard let _ = favoritePair else { return false } + + return true + } + + private func animate() { + scale += 0.2 + DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) { + scale -= 0.2 } } }
--- a/Simoleon/UI/LockedCurrencyPicker.swift Sat Aug 28 11:15:41 2021 +0100 +++ b/Simoleon/UI/LockedCurrencyPicker.swift Sat Aug 28 19:17:55 2021 +0100 @@ -7,25 +7,25 @@ import SwiftUI -struct LockedCurrencyPicker: View { - @Environment(\.managedObjectContext) private var viewContext - @FetchRequest(sortDescriptors: []) private var defaultCurrency: FetchedResults<DefaultCurrency> - - var body: some View { - HStack { - Text("Default currency") - Spacer() +//struct LockedCurrencyPicker: View { +// @Environment(\.managedObjectContext) private var viewContext +// @FetchRequest(sortDescriptors: []) private var defaultCurrency: FetchedResults<DefaultCurrency> +// +// var body: some View { +// HStack { +// Text("Default currency") +// Spacer() // Text(defaultCurrency.first?.pair ?? "USD/GBP") // .foregroundColor(.secondary) - - Image(systemName: "lock") - .foregroundColor(.secondary) - } - } -} - -struct LockedCurrencyPicker_Previews: PreviewProvider { - static var previews: some View { - LockedCurrencyPicker() - } -} +// +// Image(systemName: "lock") +// .foregroundColor(.secondary) +// } +// } +//} +// +//struct LockedCurrencyPicker_Previews: PreviewProvider { +// static var previews: some View { +// LockedCurrencyPicker() +// } +//}