# HG changeset patch # User Dennis Concepcion Martin # Date 1629396776 -3600 # Node ID 6eac99e99b969d22c5cc31777541058796566b30 # Parent 07b5d7386e6e0ccba394838c4966188bfe16c24f Add error handling to read json function diff -r 07b5d7386e6e -r 6eac99e99b96 Simoleon.xcodeproj/project.pbxproj --- a/Simoleon.xcodeproj/project.pbxproj Thu Aug 19 19:12:31 2021 +0100 +++ b/Simoleon.xcodeproj/project.pbxproj Thu Aug 19 19:12:56 2021 +0100 @@ -12,7 +12,8 @@ 950A377826A820F800CAB175 /* DefaultCurrency+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = 950A377526A820F400CAB175 /* DefaultCurrency+CoreDataClass.swift */; }; 9522BEA926B5A4D20076B098 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9522BEA826B5A4D20076B098 /* AppDelegate.swift */; }; 9522BEAB26B5AACB0076B098 /* ListModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9522BEAA26B5AACB0076B098 /* ListModifier.swift */; }; - 9555933A269B0AB8000FD726 /* ParseJson.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95559339269B0AB8000FD726 /* ParseJson.swift */; }; + 9522CD9D26CED2E100DD9D03 /* ErrorHandling.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9522CD9C26CED2E100DD9D03 /* ErrorHandling.swift */; }; + 9555933A269B0AB8000FD726 /* Read.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95559339269B0AB8000FD726 /* Read.swift */; }; 95561E3F26AF25EF00CCB543 /* SubscriptionFeature.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95561E3E26AF25EF00CCB543 /* SubscriptionFeature.swift */; }; 95562D4D26A8962A0047E778 /* StoreKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 95562D4C26A8962A0047E778 /* StoreKit.framework */; }; 95562D5226A8AEF60047E778 /* Purchases in Frameworks */ = {isa = PBXBuildFile; productRef = 95562D5126A8AEF60047E778 /* Purchases */; }; @@ -111,7 +112,8 @@ 950A377626A820F400CAB175 /* DefaultCurrency+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DefaultCurrency+CoreDataProperties.swift"; sourceTree = ""; }; 9522BEA826B5A4D20076B098 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 9522BEAA26B5AACB0076B098 /* ListModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListModifier.swift; sourceTree = ""; }; - 95559339269B0AB8000FD726 /* ParseJson.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParseJson.swift; sourceTree = ""; }; + 9522CD9C26CED2E100DD9D03 /* ErrorHandling.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ErrorHandling.swift; sourceTree = ""; }; + 95559339269B0AB8000FD726 /* Read.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Read.swift; sourceTree = ""; }; 95561E3E26AF25EF00CCB543 /* SubscriptionFeature.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SubscriptionFeature.swift; sourceTree = ""; }; 95562D4C26A8962A0047E778 /* StoreKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = StoreKit.framework; path = System/Library/Frameworks/StoreKit.framework; sourceTree = SDKROOT; }; 956088B526B9307600A4FD6C /* SnapshotHelper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SnapshotHelper.swift; path = fastlane/SnapshotHelper.swift; sourceTree = ""; }; @@ -261,7 +263,7 @@ 95559338269B0AAA000FD726 /* Functions */ = { isa = PBXGroup; children = ( - 95559339269B0AB8000FD726 /* ParseJson.swift */, + 95559339269B0AB8000FD726 /* Read.swift */, 9585BB1126A6B71B00E3193E /* ReadConfig.swift */, 9585BB1326A6B7F400E3193E /* NetworkRequest.swift */, 9585BB1926A6E8FD00E3193E /* SimpleSuccess.swift */, @@ -370,6 +372,7 @@ 95D8C8C626A95D2900BCC188 /* SubscriptionPaywall.swift */, 95C5B22B2697752700941585 /* Assets.xcassets */, 95C5B2302697752700941585 /* Persistence.swift */, + 9522CD9C26CED2E100DD9D03 /* ErrorHandling.swift */, 95C5B2352697752700941585 /* Info.plist */, 95C5B2322697752700941585 /* Simoleon.xcdatamodeld */, 95E76435269DFC1A008E9F31 /* LaunchScreen.storyboard */, @@ -672,6 +675,7 @@ 95C5179926A5EC9F00BC2B24 /* FavoriteButton.swift in Sources */, 95C5179C26A5EFBE00BC2B24 /* Favorite+CoreDataClass.swift in Sources */, 950A377826A820F800CAB175 /* DefaultCurrency+CoreDataClass.swift in Sources */, + 9522CD9D26CED2E100DD9D03 /* ErrorHandling.swift in Sources */, 95C5B2312697752700941585 /* Persistence.swift in Sources */, 9585BB1226A6B71B00E3193E /* ReadConfig.swift in Sources */, 95AEBC9526A03ECB00613729 /* ContentView.swift in Sources */, @@ -682,7 +686,7 @@ 95D8C8CD26A9784500BCC188 /* SubscribeButton.swift in Sources */, 950A377726A820F800CAB175 /* DefaultCurrency+CoreDataProperties.swift in Sources */, 9585BB1A26A6E8FD00E3193E /* SimpleSuccess.swift in Sources */, - 9555933A269B0AB8000FD726 /* ParseJson.swift in Sources */, + 9555933A269B0AB8000FD726 /* Read.swift in Sources */, 95D8C8CF26A98A7900BCC188 /* RestoreButton.swift in Sources */, 95C5179D26A5EFBE00BC2B24 /* Favorite+CoreDataProperties.swift in Sources */, 95C5179F26A5F34200BC2B24 /* Favorites.swift in Sources */, diff -r 07b5d7386e6e -r 6eac99e99b96 Simoleon/Conversion.swift --- a/Simoleon/Conversion.swift Thu Aug 19 19:12:31 2021 +0100 +++ b/Simoleon/Conversion.swift Thu Aug 19 19:12:56 2021 +0100 @@ -18,8 +18,6 @@ @State private var showingCurrencySelector = false @State private var amountIsEditing = false - let currencyMetadata: [String: CurrencyMetadataModel] = parseJson("CurrencyMetadata.json") - var body: some View { ScrollView(showsIndicators: false) { VStack(alignment: .leading) { diff -r 07b5d7386e6e -r 6eac99e99b96 Simoleon/ErrorHandling.swift --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Simoleon/ErrorHandling.swift Thu Aug 19 19:12:56 2021 +0100 @@ -0,0 +1,14 @@ +// +// ErrorHandling.swift +// Simoleon +// +// Created by Dennis Concepción Martín on 19/8/21. +// + +import Foundation + +enum JsonErrors: Error { + case fileMissing + case loadFailed(cause: String) + case parseFailed(cause: String) +} diff -r 07b5d7386e6e -r 6eac99e99b96 Simoleon/Functions/ParseJson.swift --- a/Simoleon/Functions/ParseJson.swift Thu Aug 19 19:12:31 2021 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,32 +0,0 @@ -// -// ParseJson.swift -// Simoleon -// -// Created by Dennis Concepción Martín on 11/07/2021. -// - -import Foundation - - -// Read JSON File -func parseJson(_ filename: String) -> T { - let data: Data - - guard let file = Bundle.main.url(forResource: filename, withExtension: nil) - else { - fatalError("Couldn't find \(filename) in main bundle.") - } - - do { - data = try Data(contentsOf: file) - } catch { - fatalError("Couldn't load \(filename) from main bundle:\n\(error)") - } - - do { - let decoder = JSONDecoder() - return try decoder.decode(T.self, from: data) - } catch { - fatalError("Couldn't parse \(filename) as \(T.self):\n\(error)") - } -} diff -r 07b5d7386e6e -r 6eac99e99b96 Simoleon/Functions/Read.swift --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Simoleon/Functions/Read.swift Thu Aug 19 19:12:56 2021 +0100 @@ -0,0 +1,32 @@ +// +// ParseJson.swift +// Simoleon +// +// Created by Dennis Concepción Martín on 11/07/2021. +// + +import Foundation + + +// Read JSON File +func read(json filename: String) throws -> T { + let data: Data + + guard let file = Bundle.main.url(forResource: filename, withExtension: nil) + else { + throw JsonErrors.fileMissing + } + + do { + data = try Data(contentsOf: file) + } catch { + throw JsonErrors.loadFailed(cause: error.localizedDescription) + } + + do { + let decoder = JSONDecoder() + return try decoder.decode(T.self, from: data) + } catch { + throw JsonErrors.parseFailed(cause: error.localizedDescription) + } +} diff -r 07b5d7386e6e -r 6eac99e99b96 Simoleon/Helpers/ConversionBox.swift --- a/Simoleon/Helpers/ConversionBox.swift Thu Aug 19 19:12:31 2021 +0100 +++ b/Simoleon/Helpers/ConversionBox.swift Thu Aug 19 19:12:56 2021 +0100 @@ -14,10 +14,9 @@ @Binding var showingConversion: Bool @Binding var amountIsEditing: Bool - let currencyMetadata: [String: CurrencyMetadataModel] = parseJson("CurrencyMetadata.json") - var body: some View { VStack(alignment: .leading) { + let currencyMetadata: [String: CurrencyMetadataModel] = try! read(json: "CurrencyMetadata.json") let currencies = currencyPair.split(separator: "/") Text("\(currencyMetadata[String(currencies[0])]!.name) (\(String(currencies[0])))") .font(.callout) diff -r 07b5d7386e6e -r 6eac99e99b96 Simoleon/Helpers/CurrencyRow.swift --- a/Simoleon/Helpers/CurrencyRow.swift Thu Aug 19 19:12:31 2021 +0100 +++ b/Simoleon/Helpers/CurrencyRow.swift Thu Aug 19 19:12:56 2021 +0100 @@ -10,10 +10,10 @@ struct CurrencyRow: View { var currencyPairName: String var isLocked: Bool? - let currencyMetadata: [String: CurrencyMetadataModel] = parseJson("CurrencyMetadata.json") var body: some View { HStack { + let currencyMetadata: [String: CurrencyMetadataModel] = try! read(json: "CurrencyMetadata.json") let currencies = currencyPairName.split(separator: "/") Image(currencyMetadata[String(currencies[0])]!.flag) .resizable() diff -r 07b5d7386e6e -r 6eac99e99b96 Simoleon/Helpers/CurrencySelector.swift --- a/Simoleon/Helpers/CurrencySelector.swift Thu Aug 19 19:12:31 2021 +0100 +++ b/Simoleon/Helpers/CurrencySelector.swift Thu Aug 19 19:12:56 2021 +0100 @@ -19,8 +19,6 @@ @State private var alertMessage = "" @State private var showingAlert = false - var currencyPairs: [CurrencyPairModel] = parseJson("CurrencyPairs.json") - /* If searched currency string is empty: * Show all currencies @@ -28,6 +26,7 @@ * Show filtered list of currencies containing searched currency string */ var searchResults: [CurrencyPairModel] { + let currencyPairs: [CurrencyPairModel] = try! read(json: "CurrencyPairs.json") if searchCurrency.isEmpty { return currencyPairs.sorted { !$0.isLocked && $1.isLocked } } else { diff -r 07b5d7386e6e -r 6eac99e99b96 Simoleon/Settings.swift --- a/Simoleon/Settings.swift Thu Aug 19 19:12:31 2021 +0100 +++ b/Simoleon/Settings.swift Thu Aug 19 19:12:56 2021 +0100 @@ -20,8 +20,6 @@ @State private var showingAlert = false @State private var searchCurrency = "" - let currencyPairs: [CurrencyPairModel] = parseJson("CurrencyPairs.json") - /* If searched currency string is empty: * Show all currencies @@ -29,6 +27,7 @@ * Show filtered list of currencies containing searched currency string */ var searchResults: [CurrencyPairModel] { + let currencyPairs: [CurrencyPairModel] = try! read(json: "CurrencyPairs.json") if searchCurrency.isEmpty { return currencyPairs.sorted { $0.name < $1.name } } else {