Mercurial > public > simoleon
changeset 154:8afba86ab8dd
Refactor code
author | Dennis Concepcion Martin <dennisconcepcionmartin@gmail.com> |
---|---|
date | Wed, 25 Aug 2021 10:43:12 +0100 |
parents | 2590ee472aa9 |
children | 681f2cbe8c7f |
files | Simoleon/Functions/NetworkRequest.swift Simoleon/Functions/Read.swift Simoleon/Functions/ReadConfig.swift Simoleon/Functions/SimpleSuccess.swift Simoleon/Helpers/ListModifier.swift Simoleon/Jobs/CurrenciesController.swift Simoleon/Jobs/FileController.swift Simoleon/Jobs/HapticsController.swift Simoleon/Jobs/NetworkController.swift Simoleon/Models/CurrencyDetailsModel.swift Simoleon/Models/CurrencyQuoteModel.swift Simoleon/Settings.swift Simoleon/SimoleonApp.swift SimoleonTests/SimoleonTests.swift |
diffstat | 14 files changed, 195 insertions(+), 126 deletions(-) [+] |
line wrap: on
line diff
--- a/Simoleon/Functions/NetworkRequest.swift Mon Aug 23 17:14:47 2021 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,37 +0,0 @@ -// -// Request.swift -// Simoleon -// -// Created by Dennis Concepción Martín on 20/07/2021. -// - -import SwiftUI - -func networkRequest<T: Decodable>(url: String, model: T.Type, completion: @escaping (_ result: T) -> Void) { - - // We take some model data T.Type - guard let url = URL(string: url) else { - print("Invalid URL") - return - } - - let request = URLRequest(url: url) - URLSession.shared.dataTask(with: request) { data, response, error in - if let data = data { - do { - // Decode response with the model passed - let decodedResponse = try JSONDecoder().decode(model, from: data) - DispatchQueue.main.async { - completion(decodedResponse) - } - return - } catch { - // Return error regarding the escaping code - print(error) - } - } - // Error with the request - print("Fetch failed: \(error?.localizedDescription ?? "Unknown error")") - } - .resume() -}
--- a/Simoleon/Functions/Read.swift Mon Aug 23 17:14:47 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 read<T: Decodable>(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) - } -}
--- a/Simoleon/Functions/ReadConfig.swift Mon Aug 23 17:14:47 2021 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,13 +0,0 @@ -// -// ReadConfig.swift -// Simoleon -// -// Created by Dennis Concepción Martín on 20/07/2021. -// - -import SwiftUI - -func readConfig(_ key: String) -> String? { - return (Bundle.main.infoDictionary?[key] as? String)? - .replacingOccurrences(of: "\\", with: "") -}
--- a/Simoleon/Functions/SimpleSuccess.swift Mon Aug 23 17:14:47 2021 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,14 +0,0 @@ -// -// SimpleSuccess.swift -// Simoleon -// -// Created by Dennis Concepción Martín on 20/07/2021. -// - -import SwiftUI - -// Haptics -func simpleSuccess() { - let generator = UINotificationFeedbackGenerator() - generator.notificationOccurred(.success) -}
--- a/Simoleon/Helpers/ListModifier.swift Mon Aug 23 17:14:47 2021 +0100 +++ b/Simoleon/Helpers/ListModifier.swift Wed Aug 25 10:43:12 2021 +0100 @@ -12,10 +12,11 @@ content .id(UUID()) .listStyle(PlainListStyle()) - .gesture(DragGesture() + .gesture( + DragGesture() .onChanged({ _ in UIApplication.shared.dismissKeyboard() - }) + }) ) } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Simoleon/Jobs/CurrenciesController.swift Wed Aug 25 10:43:12 2021 +0100 @@ -0,0 +1,54 @@ +// +// GetCompatibleCurrencies.swift +// Simoleon +// +// Created by Dennis Concepción Martín on 24/8/21. +// + +import Foundation + +class CurrenciesController { + let fileController = FileController() + + func get(currenciesCompatibleWith currencySymbol: String?, currencies: Bool?) -> [String] { + // If currencies not false -> return all currencies + guard currencies == false else { return allCurrencies() } + + // This block won't be executed if the previous check fails + return compatibleCurrencies(with: currencySymbol!) + } + + /* + * Input all currencies supported by vendor + * Return individual currency symbols without duplicates + */ + private func allCurrencies() -> [String] { + let currencyPairsSupported: [String] = try! fileController.read(json: "CurrencyPairsSupported.json") + + var currencies = Set<String>() + for currencyPairSupported in currencyPairsSupported { + let currency = currencyPairSupported.components(separatedBy: "/")[0] + currencies.insert(currency) + } + + return Array(currencies) + } + + /* + * Given the first symbol of the currency pair + * Return all compatible symbols + */ + private func compatibleCurrencies(with currencySymbol: String) -> [String] { + let currencyPairsSupported: [String] = try! fileController.read(json: "CurrencyPairsSupported.json") + + var currencies = [String]() + for currencyPairSupported in currencyPairsSupported { + if currencyPairSupported.hasPrefix(currencySymbol) { + let compatibleCurrency = currencyPairSupported.components(separatedBy: "/")[1] + currencies.append(compatibleCurrency) + } + } + + return currencies + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Simoleon/Jobs/FileController.swift Wed Aug 25 10:43:12 2021 +0100 @@ -0,0 +1,44 @@ +// +// ReadConfig.swift +// Simoleon +// +// Created by Dennis Concepción Martín on 20/07/2021. +// + +import Foundation + +class FileController { + + /* + Read configuration variables from Config.xconfig + */ + func readConfigVariable(withKey: String) -> String? { + return (Bundle.main.infoDictionary?[withKey] as? String)? + .replacingOccurrences(of: "\\", with: "") + } + + /* + Decode and read json file + */ + func read<T: Decodable>(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) + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Simoleon/Jobs/HapticsController.swift Wed Aug 25 10:43:12 2021 +0100 @@ -0,0 +1,19 @@ +// +// SimpleSuccess.swift +// Simoleon +// +// Created by Dennis Concepción Martín on 20/07/2021. +// + +import SwiftUI + +class HapticsController { + + /* + Default haptic for success action + */ + func simpleSuccess() { + let generator = UINotificationFeedbackGenerator() + generator.notificationOccurred(.success) + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Simoleon/Jobs/NetworkController.swift Wed Aug 25 10:43:12 2021 +0100 @@ -0,0 +1,43 @@ +// +// Request.swift +// Simoleon +// +// Created by Dennis Concepción Martín on 20/07/2021. +// + +import Foundation + +class NetworkController { + + /* + Get http response and decode it with specified model + */ + func httpRequest<T: Decodable>(url: String, model: T.Type, completion: @escaping (_ result: T) -> Void) { + + // We take some model data T.Type + guard let url = URL(string: url) else { + print("Invalid URL") + return + } + + let request = URLRequest(url: url) + URLSession.shared.dataTask(with: request) { data, response, error in + if let data = data { + do { + // Decode response with the model passed + let decodedResponse = try JSONDecoder().decode(model, from: data) + DispatchQueue.main.async { + completion(decodedResponse) + } + return + } catch { + // Return error regarding the escaping code + print(error) + } + } + // Error with the request + print("Fetch failed: \(error?.localizedDescription ?? "Unknown error")") + } + .resume() + } +}
--- a/Simoleon/Models/CurrencyDetailsModel.swift Mon Aug 23 17:14:47 2021 +0100 +++ b/Simoleon/Models/CurrencyDetailsModel.swift Wed Aug 25 10:43:12 2021 +0100 @@ -7,7 +7,6 @@ import Foundation - struct CurrencyDetailsModel: Codable { var name: String var flag: String
--- a/Simoleon/Models/CurrencyQuoteModel.swift Mon Aug 23 17:14:47 2021 +0100 +++ b/Simoleon/Models/CurrencyQuoteModel.swift Wed Aug 25 10:43:12 2021 +0100 @@ -5,7 +5,7 @@ // Created by Dennis Concepción Martín on 15/07/2021. // -import SwiftUI +import Foundation struct CurrencyQuoteModel: Codable, Hashable { var symbol: String?
--- a/Simoleon/Settings.swift Mon Aug 23 17:14:47 2021 +0100 +++ b/Simoleon/Settings.swift Wed Aug 25 10:43:12 2021 +0100 @@ -20,6 +20,8 @@ @State private var showingAlert = false @State private var searchCurrency = "" + let fileController = FileController() + /* If searched currency string is empty: * Show all currencies @@ -27,7 +29,7 @@ * Show filtered list of currencies containing searched currency string */ var searchResults: [String] { - let currencyPairsSupported: [String] = try! read(json: "CurrencyPairsSupported.json") + let currencyPairsSupported: [String] = try! fileController.read(json: "CurrencyPairsSupported.json") if searchCurrency.isEmpty { return currencyPairsSupported.sorted() } else { @@ -114,11 +116,11 @@ * View is appearing after user selected another default currency * Save it to core data */ - if selectedDefaultCurrency == "" { - selectedDefaultCurrency = defaultCurrency.first?.pair ?? "USD/GBP" - } else { - setCoreData() - } +// if selectedDefaultCurrency == "" { +// selectedDefaultCurrency = defaultCurrency.first?.pair ?? "USD/GBP" +// } else { +// setCoreData() +// } } .listStyle(InsetGroupedListStyle()) .navigationTitle("Settings") @@ -131,21 +133,21 @@ } // Save default currency to core data - private func setCoreData() { - if defaultCurrency.isEmpty { // If it's empty -> add record - let defaultCurrency = DefaultCurrency(context: viewContext) - defaultCurrency.pair = selectedDefaultCurrency - - do { - try viewContext.save() - } catch { - print(error.localizedDescription) - } - } else { // If not, update record - defaultCurrency.first?.pair = selectedDefaultCurrency - try? viewContext.save() - } - } +// private func setCoreData() { +// if defaultCurrency.isEmpty { // If it's empty -> add record +// let defaultCurrency = DefaultCurrency(context: viewContext) +// defaultCurrency.pair = selectedDefaultCurrency +// +// do { +// try viewContext.save() +// } catch { +// print(error.localizedDescription) +// } +// } else { // If not, update record +// defaultCurrency.first?.pair = selectedDefaultCurrency +// try? viewContext.save() +// } +// } // Check if user subscription is active private func checkEntitlement() {
--- a/Simoleon/SimoleonApp.swift Mon Aug 23 17:14:47 2021 +0100 +++ b/Simoleon/SimoleonApp.swift Wed Aug 25 10:43:12 2021 +0100 @@ -12,9 +12,11 @@ struct SimoleonApp: App { @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate let persistenceController = PersistenceController.shared + let fileController = FileController() init() { - Purchases.configure(withAPIKey: "\(readConfig("PURCHASES_KEY")!)") + let apiKey = fileController.readConfigVariable(withKey: "PURCHASES_KEY")! + Purchases.configure(withAPIKey: apiKey) } var body: some Scene {
--- a/SimoleonTests/SimoleonTests.swift Mon Aug 23 17:14:47 2021 +0100 +++ b/SimoleonTests/SimoleonTests.swift Wed Aug 25 10:43:12 2021 +0100 @@ -9,6 +9,7 @@ @testable import Simoleon class SimoleonTests: XCTestCase { + let fileController = FileController() override func setUpWithError() throws { // Put setup code here. This method is called before the invocation of each test method in the class. @@ -20,18 +21,18 @@ } func testReadJson() throws { - let currencyPairsSupported: [String]? = try? read(json: "CurrencyPairsSupported.json") + let currencyPairsSupported: [String]? = try? fileController.read(json: "CurrencyPairsSupported.json") XCTAssertNotNil(currencyPairsSupported, "An error occurred while reading CurrencyPairsSupported.json") - let currencyDetails: [String: CurrencyDetailsModel]? = try? read(json: "CurrencyDetails.json") + let currencyDetails: [String: CurrencyDetailsModel]? = try? fileController.read(json: "CurrencyDetails.json") XCTAssertNotNil(currencyDetails, "An error occurred while reading CurrencyDetails.json") } func testCurrencyExistence() throws { - let currencyDetails: [String: CurrencyDetailsModel] = try! read(json: "CurrencyDetails.json") + let currencyDetails: [String: CurrencyDetailsModel] = try! fileController.read(json: "CurrencyDetails.json") // Remove duplicates from currency pairs supported - let currencyPairsSupported: [String] = try! read(json: "CurrencyPairsSupported.json") + let currencyPairsSupported: [String] = try! fileController.read(json: "CurrencyPairsSupported.json") var currenciesSupported = Set<String>() for currencyPairSupported in currencyPairsSupported {